先说一个暴论:自定义属性对于普通用户没有使用什么价值,数据库才是普通用户的最终归宿。
自定义属性不支持中文名,这一条就可以把它枪毙了,还是让它在插件作者的手中发挥余热吧。
我们来讨论讨论基于现有数据库方案的全局属性可行性。
什么是全局属性
全局属性是 anytype 的数据库方案,详见 Anytype——思源数据库的指路明灯 - 链滴。简单来说,全局属性就是所有数据库共用属性,属性具有唯一性,一处修改,处处同步,达到属性复用的目的,一个块添加到多个数据库,这些数据库如果有同名属性 A,那么这个块就只有一个属性 A 值。
目前思源笔记不同数据库的同名属性是不互通的,就像你在多个 QQ 群可以有不同的昵称,这既是优点也是缺点,如果你只想有一个昵称,就会觉得很麻烦,需要一个个 QQ 群改过去。
全局属性方案 1
对于属性唯一性问题,最简单的解决方案就是一把梭哈,只保留一个“全局属性”数据库!把所有属性都塞到一个 json 文件里!其他数据库都是全局属性数据库的镜像数据库,新建数据库=新建视图,通过不同的视图来展示不同的属性。
这个方案需要对现有数据库的显示、操作等进行一定的修改。
显示方案的修改
需要将数据库名称栏取消,保留视图栏即可。因为所有的数据库都是全局属性数据库的镜像数据库,显示的是它的不同视图。
操作逻辑的修改
添加行的逻辑修改
不同的视图可以显示不同的属性列,但是如何对行进行限制呢?下面是数据库的一个视图的 json 定义,可以看到其中有个属性是 rowIds
,经测试 rowIds
和筛选操作无关,似乎是个预留属性,目前没起到什么作用,那么 rowIds
属性完全可以作为从全数据库中显示哪些行的依据。在新建数据库(=新建视图)的时候,视图的 rowIds
设置为空,当向视图中添加块的时候,进行如下操作:
-
如果块已经存在于全局数据库中,则将
rowId
加入到目标视图的rowIds
属性中 -
如果块不存在于全局数据库中,则
- 向全局数据库中添加一行
- 将新增行的
rowId
加入到目标视图的rowIds
属性中
-
如果添加的不是块,而是普通文本行呢?执行步骤 2。
{
"id": "20240305145356-a78x9ht",
"icon": "",
"name": "表格",
"hideAttrViewName": false,
"desc": "",
"type": "table",
"table": {
"spec": 0,
"id": "20240305145356-jkvhorr",
"columns": [
{
"id": "20240220201428-she86q1",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220203146-trhlqnq",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240221125355-h02xmfr",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220201831-kb2ybyq",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220202627-8ttud4q",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220202413-gp2dgk9",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240221113912-7xwex9g",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220202707-oldswhq",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
},
{
"id": "20240220205140-zak4f3d",
"wrap": false,
"hidden": false,
"pin": false,
"width": ""
}
],
"rowIds": [
"20241122122950-seuq0iy",
"20241112092733-le5f8s2",
"20240220201553-ezjsz1o",
"20240220201651-dny3n04",
"20240220201657-re0asqe",
"20240220201704-1udbxtc",
"20240221113424-zqw91jx",
"20240301163132-8gs4bk2",
"20240301163120-3z96swp",
"20240221122431-1uh1rbl",
"20240221122819-n1kzzs8",
"20241112135653-2n4ien0",
"20241112135730-aeyjttk",
"20241112135754-m472bmu"
],
"filters": [],
"sorts": [],
"pageSize": 50
}
}
添加列的逻辑修改
添加列时需要在弹出菜单中新增一个选项“选择全局属性”,点击后就可以将全局属性数据库的某个列添加到该视图。
全局属性方案 2
方案 1 保证了属性在工作空间内的唯一性,相当于你在多个 QQ 群全部实名制了,这时候有些小可爱就要问了:有没有可能在大部分 QQ 群中实名制,在一部分 QQ 群中使用不同昵称呢?这就是方案 2 要解决的问题。
方案 2 维持现在的一个数据库一个 json 文件,主要在 json 文件的读写上下功夫。
首先还是得内置一个“全局属性”数据库,这个数据库对于用户是隐藏的,用户能够操作的数据库就叫普通数据库吧。
全局属性数据库与普通数据库列的关联
在数据库的添加列菜单中增加“添加全局属性”、“选择全局属性”两个按钮:
-
添加全局属性
- 点击后在普通数据库和全局数据数据库中同时新增一个列,这两个列具有相同的 keyid
- 在对这个新增列命名时需要对属性名进行校验,禁止与全局属性数据库中的已有列同名。
- 将普通数据库中的所有行的 id 添加到全局数据数据库中
-
选择全局属性
- 从全局属性数据库中选择一个属性添加到普通数据库中,具有相同 keyid
- 将普通数据库中的所有行的 id 添加到全局数据数据库中
全局属性数据库与普通数据库属性值的同步
在修改普通数据库的单元格时,如果普通数据库中具有全局属性,需要将修改后的值同步到全局数据库相同行中,再同步到其他普通数据库相同行中。
相同行的判断
每行的主键列单元格都有 blockID,让普通数据库和全局数据库的相同行具有相同的 blockID 即可。
方案对比
方案 | 方案 1 | 方案 2 |
---|---|---|
数据保存 | 全部保存到全局 JSON 文件 | 内置全局属性 JSON 文件,其他数据库不变 |
特点 | 属性唯一 | 全局属性 + 数据库自有属性,比较灵活 |
主要改动 | 前端显示与操作逻辑的修改 | 后端读写的修改,需要同时读写多个 JSON 文件 |
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于