postgersql.sql 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. -- CREATE DATABASE serve;
  2. -- USE serve;
  3. -- 创建 schema(如果不存在)
  4. CREATE SCHEMA IF NOT EXISTS dev;
  5. DROP TABLE IF EXISTS dev.user;
  6. -- 在 dev schema 下创建用户表
  7. CREATE TABLE dev.user (
  8. id SERIAL PRIMARY KEY,
  9. account VARCHAR(50) NOT NULL UNIQUE,
  10. password VARCHAR(255) NOT NULL,
  11. username VARCHAR(100) NOT NULL,
  12. role VARCHAR(20) NOT NULL DEFAULT 'user' CHECK ( role IN ('user','expert','admin') ),
  13. avatar TEXT,
  14. phone_number char(11),
  15. enable INT NOT NULL DEFAULT 1,
  16. delete_flag INT NOT NULL DEFAULT 0
  17. );
  18. -- =============================================
  19. -- 钱包表
  20. -- =============================================
  21. DROP TABLE IF EXISTS dev.wallet;
  22. CREATE TABLE dev.wallet (
  23. id BIGSERIAL PRIMARY KEY,
  24. user_id BIGINT NOT NULL UNIQUE,
  25. balance DECIMAL(10,2) NOT NULL DEFAULT 0,
  26. created_at TIMESTAMP NOT NULL DEFAULT now(),
  27. updated_at TIMESTAMP NOT NULL DEFAULT now()
  28. );
  29. COMMENT ON TABLE dev.wallet IS '钱包表';
  30. COMMENT ON COLUMN dev.wallet.user_id IS '用户ID';
  31. COMMENT ON COLUMN dev.wallet.balance IS '钱包余额';
  32. CREATE UNIQUE INDEX idx_wallet_user_id ON dev.wallet(user_id);
  33. -- =============================================
  34. -- 用户扩展信息表
  35. -- =============================================
  36. DROP TABLE IF EXISTS dev.user_profile;
  37. CREATE TABLE dev.user_profile (
  38. id BIGSERIAL PRIMARY KEY,
  39. user_id BIGINT NOT NULL UNIQUE,
  40. level VARCHAR(20) NOT NULL DEFAULT 'gold' CHECK ( level IN ('gold','diamond','master') ),
  41. is_realname BOOLEAN DEFAULT FALSE,
  42. created_at TIMESTAMP NOT NULL DEFAULT now(),
  43. updated_at TIMESTAMP NOT NULL DEFAULT now()
  44. );
  45. COMMENT ON TABLE dev.user_profile IS '用户扩展信息表';
  46. COMMENT ON COLUMN dev.user_profile.level IS '等级:gold黄金 diamond钻石 master大师';
  47. COMMENT ON COLUMN dev.user_profile.is_realname IS '是否已实名认证';
  48. CREATE UNIQUE INDEX idx_up_user_id ON dev.user_profile(user_id);
  49. -- 添加注释
  50. COMMENT ON TABLE dev.user IS '用户表';
  51. COMMENT ON COLUMN dev.user.id IS '用户ID,自增主键';
  52. COMMENT ON COLUMN dev.user.account IS '账号,唯一';
  53. COMMENT ON COLUMN dev.user.password IS '密码';
  54. COMMENT ON COLUMN dev.user.username IS '用户名';
  55. COMMENT ON COLUMN dev.user.role IS '角色';
  56. COMMENT ON COLUMN dev.user.avatar IS '头像URL';
  57. COMMENT ON COLUMN dev.user.phone_number IS '手机号码';
  58. COMMENT ON COLUMN dev.user.enable IS '是否启用';
  59. COMMENT ON COLUMN dev.user.delete_flag IS '删除标记';
  60. -- 创建索引
  61. CREATE INDEX idx_user_account ON dev.user(account);
  62. CREATE INDEX idx_user_role ON dev.user(role);
  63. CREATE INDEX idx_user_enable ON dev.user(enable);
  64. CREATE INDEX idx_user_delete_flag ON dev.user(delete_flag);
  65. -- 元数据
  66. CREATE TABLE dev.meta (
  67. id SERIAL PRIMARY KEY,
  68. key VARCHAR(32) NOT NULL,
  69. value JSONB
  70. );
  71. -- 2. 添加注释
  72. COMMENT ON TABLE dev.meta IS '元数据表,用于存储键值对形式的配置或扩展属性';
  73. COMMENT ON COLUMN dev.meta.id IS '自增主键,唯一标识一条元数据记录';
  74. COMMENT ON COLUMN dev.meta.key IS '元数据的键,长度不超过32个字符,不可为空';
  75. COMMENT ON COLUMN dev.meta.value IS '元数据的值,使用 JSONB 类型存储,支持结构化数据';
  76. -- 3. 索引建议
  77. -- 业务上 key 通常需要唯一约束,且频繁用于等值查询
  78. CREATE UNIQUE INDEX idx_meta_key ON dev.meta (key);
  79. -- 若经常对 value 内部字段进行查询或过滤,可添加 GIN 索引以加速 JSONB 操作
  80. CREATE INDEX idx_meta_value_gin ON dev.meta USING GIN (value);
  81. INSERT INTO dev.meta(key, value) VALUES
  82. ('website_config','{"title": "咕咕嘎嘎论坛", "logo": "", "announcement": "欢迎访问咕咕嘎嘎论坛!", "statement": "本站所有内容仅代表发布者个人观点,平台对内容的真实性、完整性、及时性不做任何保证,请用户理性参考,谨慎打赏。"}'),
  83. ('oss_config','{"endpoint": "","region":"","bucket":"","accessKey":"","secretKey":"","publicDomain":""}');
  84. -- =============================================
  85. -- 帖子表
  86. -- =============================================
  87. DROP TABLE IF EXISTS dev.post;
  88. CREATE TABLE dev.post (
  89. id BIGSERIAL PRIMARY KEY,
  90. expert_id BIGINT NOT NULL,
  91. title VARCHAR(200) NOT NULL,
  92. content_intro TEXT,
  93. content_paid TEXT,
  94. price DECIMAL(10,2) NOT NULL,
  95. hit_status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK ( hit_status IN ('pending','hit','miss') ),
  96. view_count INT NOT NULL DEFAULT 0,
  97. publish_time TIMESTAMP NOT NULL DEFAULT now(),
  98. expire_time TIMESTAMP NOT NULL,
  99. delete_flag INT DEFAULT 0,
  100. created_at TIMESTAMP NOT NULL DEFAULT now(),
  101. updated_at TIMESTAMP NOT NULL DEFAULT now()
  102. );
  103. COMMENT ON TABLE dev.post IS '帖子表';
  104. COMMENT ON COLUMN dev.post.id IS '帖子ID';
  105. COMMENT ON COLUMN dev.post.expert_id IS '发布专家ID';
  106. COMMENT ON COLUMN dev.post.title IS '帖子标题(含期号)';
  107. COMMENT ON COLUMN dev.post.content_intro IS '内容简介(公开)';
  108. COMMENT ON COLUMN dev.post.content_paid IS '付费内容';
  109. COMMENT ON COLUMN dev.post.price IS '打赏金额';
  110. COMMENT ON COLUMN dev.post.hit_status IS '命中状态:pending待确认 hit命中 miss未命中';
  111. COMMENT ON COLUMN dev.post.view_count IS '查看人数(管理员可修改)';
  112. COMMENT ON COLUMN dev.post.publish_time IS '发布时间';
  113. COMMENT ON COLUMN dev.post.expire_time IS '过期时间,超出此时间自动转为公开';
  114. CREATE INDEX idx_post_expert_id ON dev.post(expert_id);
  115. CREATE INDEX idx_post_hit_status ON dev.post(hit_status);
  116. CREATE INDEX idx_post_expire_time ON dev.post(expire_time);
  117. CREATE INDEX idx_post_delete_flag ON dev.post(delete_flag);
  118. -- =============================================
  119. -- 帖子访问记录表
  120. -- =============================================
  121. DROP TABLE IF EXISTS dev.post_view_record;
  122. CREATE TABLE dev.post_view_record (
  123. id BIGSERIAL PRIMARY KEY,
  124. post_id BIGINT NOT NULL,
  125. user_id BIGINT NOT NULL,
  126. view_time TIMESTAMP NOT NULL DEFAULT now(),
  127. created_at TIMESTAMP NOT NULL DEFAULT now(),
  128. updated_at TIMESTAMP NOT NULL DEFAULT now()
  129. );
  130. COMMENT ON TABLE dev.post_view_record IS '帖子访问记录表';
  131. COMMENT ON COLUMN dev.post_view_record.post_id IS '帖子ID';
  132. COMMENT ON COLUMN dev.post_view_record.user_id IS '访问用户ID';
  133. CREATE UNIQUE INDEX idx_pvr_post_user ON dev.post_view_record(post_id, user_id);
  134. -- =============================================
  135. -- 打赏订单表
  136. -- =============================================
  137. DROP TABLE IF EXISTS dev.order_tip;
  138. CREATE TABLE dev.order_tip (
  139. id BIGSERIAL PRIMARY KEY,
  140. user_id BIGINT NOT NULL,
  141. post_id BIGINT NOT NULL,
  142. expert_id BIGINT NOT NULL,
  143. amount DECIMAL(10,2) NOT NULL,
  144. status VARCHAR(20) NOT NULL DEFAULT 'completed',
  145. create_time TIMESTAMP NOT NULL DEFAULT now(),
  146. created_at TIMESTAMP NOT NULL DEFAULT now(),
  147. updated_at TIMESTAMP NOT NULL DEFAULT now()
  148. );
  149. COMMENT ON TABLE dev.order_tip IS '打赏订单表';
  150. COMMENT ON COLUMN dev.order_tip.user_id IS '打赏人ID';
  151. COMMENT ON COLUMN dev.order_tip.post_id IS '帖子ID';
  152. COMMENT ON COLUMN dev.order_tip.expert_id IS '被打赏专家ID';
  153. COMMENT ON COLUMN dev.order_tip.amount IS '打赏金额';
  154. CREATE INDEX idx_ot_user_id ON dev.order_tip(user_id);
  155. CREATE INDEX idx_ot_post_id ON dev.order_tip(post_id);
  156. CREATE INDEX idx_ot_expert_id ON dev.order_tip(expert_id);
  157. -- =============================================
  158. -- 钱包流水表
  159. -- =============================================
  160. DROP TABLE IF EXISTS dev.wallet_transaction;
  161. CREATE TABLE dev.wallet_transaction (
  162. id BIGSERIAL PRIMARY KEY,
  163. user_id BIGINT NOT NULL,
  164. type VARCHAR(20) NOT NULL,
  165. amount DECIMAL(10,2) NOT NULL,
  166. balance_before DECIMAL(10,2),
  167. balance_after DECIMAL(10,2),
  168. status VARCHAR(20) NOT NULL DEFAULT 'success',
  169. remark VARCHAR(255),
  170. review_time TIMESTAMP,
  171. created_at TIMESTAMP NOT NULL DEFAULT now(),
  172. updated_at TIMESTAMP NOT NULL DEFAULT now()
  173. );
  174. COMMENT ON TABLE dev.wallet_transaction IS '钱包流水表';
  175. COMMENT ON COLUMN dev.wallet_transaction.user_id IS '用户ID';
  176. COMMENT ON COLUMN dev.wallet_transaction.type IS '流水类型:recharge充值 withdraw提现 tip_out打赏支出 admin_adjust管理员调整';
  177. COMMENT ON COLUMN dev.wallet_transaction.amount IS '金额,正数为收入,负数为支出';
  178. CREATE INDEX idx_wt_user_id ON dev.wallet_transaction(user_id);
  179. CREATE INDEX idx_wt_type ON dev.wallet_transaction(type);
  180. -- =============================================
  181. -- 实名认证表
  182. -- =============================================
  183. DROP TABLE IF EXISTS dev.realname_auth;
  184. CREATE TABLE dev.realname_auth (
  185. id BIGSERIAL PRIMARY KEY,
  186. user_id BIGINT NOT NULL UNIQUE,
  187. real_name VARCHAR(50) NOT NULL,
  188. id_card VARCHAR(18) NOT NULL,
  189. id_card_front TEXT,
  190. id_card_back TEXT,
  191. status VARCHAR(20) NOT NULL DEFAULT 'pending' CHECK ( status IN ('pending','approved','rejected') ),
  192. reject_reason VARCHAR(255),
  193. review_time TIMESTAMP,
  194. created_at TIMESTAMP NOT NULL DEFAULT now(),
  195. updated_at TIMESTAMP NOT NULL DEFAULT now()
  196. );
  197. COMMENT ON TABLE dev.realname_auth IS '实名认证表';
  198. COMMENT ON COLUMN dev.realname_auth.user_id IS '用户ID';
  199. COMMENT ON COLUMN dev.realname_auth.real_name IS '真实姓名';
  200. COMMENT ON COLUMN dev.realname_auth.id_card IS '身份证号';
  201. COMMENT ON COLUMN dev.realname_auth.status IS '认证状态:pending待审核 approved通过 rejected驳回';
  202. CREATE UNIQUE INDEX idx_ra_user_id ON dev.realname_auth(user_id);
  203. -- =============================================
  204. -- 系统通知表
  205. -- =============================================
  206. DROP TABLE IF EXISTS dev.notification;
  207. CREATE TABLE dev.notification (
  208. id BIGSERIAL PRIMARY KEY,
  209. user_id BIGINT NOT NULL,
  210. type VARCHAR(30) NOT NULL,
  211. title VARCHAR(100),
  212. content TEXT,
  213. is_read BOOLEAN DEFAULT FALSE,
  214. created_at TIMESTAMP NOT NULL DEFAULT now(),
  215. updated_at TIMESTAMP NOT NULL DEFAULT now()
  216. );
  217. COMMENT ON TABLE dev.notification IS '系统通知表';
  218. COMMENT ON COLUMN dev.notification.user_id IS '接收人ID';
  219. COMMENT ON COLUMN dev.notification.type IS '通知类型:tip_success recharge_success withdraw_request withdraw_success withdraw_failed system';
  220. CREATE INDEX idx_notif_user_id ON dev.notification(user_id);
  221. CREATE INDEX idx_notif_is_read ON dev.notification(is_read);
  222. -- =============================================
  223. -- OSS附件表
  224. -- =============================================
  225. DROP TABLE IF EXISTS dev.attachment;
  226. CREATE TABLE dev.attachment (
  227. id BIGSERIAL PRIMARY KEY,
  228. user_id BIGINT NOT NULL,
  229. url TEXT NOT NULL,
  230. type VARCHAR(20),
  231. created_at TIMESTAMP NOT NULL DEFAULT now(),
  232. updated_at TIMESTAMP NOT NULL DEFAULT now()
  233. );
  234. COMMENT ON TABLE dev.attachment IS 'OSS附件表';
  235. COMMENT ON COLUMN dev.attachment.user_id IS '上传人ID';
  236. COMMENT ON COLUMN dev.attachment.url IS 'OSS文件URL';
  237. COMMENT ON COLUMN dev.attachment.type IS '附件类型:avatar头像 id_card身份证 post_image帖子图片';
  238. CREATE INDEX idx_attachment_user_id ON dev.attachment(user_id);