平台已创建好5个供用户直接使用的业务表
{
id: bigint,
auth: bigint, // 创建该记录的用户ID
type: text, // 类型,方便分类及搜索
name: text, // 唯一名,有时用来代替ID更容易理解与记忆
x: {}, // 详细信息
y: {} // 附加信息,存放不让用户直接修改/不常变动的信息
}
我们通常把具体的、能喊得上名字的数据存放在产品表中,不管是有形的实体物品还是无形的虚拟产品
{
id: bigint,
phone: text, // 手机号码,登录用
mail: text, // 邮件地址,登录用
role: [], // 角色,控制权限用
wx: {}, // 微信账号信息
x: {}, // 详细信息
y: {} // 附加信息,存放不让用户直接修改/不常变动的信息
}
{
id: bigint,
auth: bigint, // 创建该记录的用户ID
type: text, // 订单分类
desc: text, // 订单描述
total: numeric, // 付款总金额
refund: numeric, // 退款金额
x: {}, // 详细信息
y: {}, // 附加信息,存放不让用户直接修改/不常变动的信息
z: {} // 支付信息,由平台维护
}
{
id: bigint,
auth: bigint, // 创建该记录时用户ID
type: text, // 类型,i是image, v是video, f是file
url: text, // 资源在对象存储服务器的地址
name: text, // 文件名
ext: text, // 文件后缀/扩展名
size: integer, // 文件大小(K)
del: timestamp, // 删除时间戳
x: {}, // 详细信息
y: {} // 附加信息,存放不让用户直接修改/不常变动的信息
}
存放用户上传的图片/视频/文件信息,此表在用户上传资源时由平台自动创建。
{
id: bigint,
type: text, // 类型,直观表达此数据是什么东西
key: text, // 关键信息,确保同type的组合是唯一的
x: {}, // 详细信息
y: {} // 附加信息,存放不让用户直接修改/不常变动的信息
}
由type和key两个字段组成联合主键,不能归到其它表的才存入此表。
很多时候key是另一条数据的id,表示它是那一条数据相关联的子表数据/附属信息。
每个表都有一个由平台统一生成的主键id
;它由16位数字组成,可以用isId()
来判断参数是否是有效ID。
它前10位是该记录的创建时间(精确到秒),可以用date()
把id
转换成时间。还可以用id()
通过一个时间参数来构建一个id
并以此来查询数据库。
除了用户表都有一个必填的类型type
字段,用来对数据进行分类。
type/name/key应避免使用特殊字符,如空格})*'",:@%$
。
具体的业务数据通常都存放在各表的json类型的x
字段里,允许嵌套数组,所以可以存放非常复杂的数据,传统子表里的数据都可以一起塞到里面。那到底是分母子表存储还是嵌套存储呢?
通常无需单独拎出来查询的、信息量少的、记录条数有限的数据适合嵌套,否则就应该分开存储。
比如简历中的工作经历列表就可以嵌套,因为一个人的工作经历数量有限、不会出现单独查工作经历而不查人的情况。再比如会计凭证中的分录也可以嵌套,每个凭证都有至少一个借和一个贷分录,但总量不会太多。
而一个用户发布的文章就不应该嵌套的用户表中,一篇文章的评论也不应该嵌套的文章表里,因为文章/评论需要单独查询,而且它们的数量也难以估计。