V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shade
V2EX  ›  程序员

关系数据库存储属性变量可变的 Java 对象,怎么优化 sql

  •  
  •   shade · 2023-01-15 21:15:36 +08:00 · 2364 次点击
    这是一个创建于 676 天前的主题,其中的信息可能已经有所发展或是发生改变。

    像这篇文章( https://www.codenong.com/13466954/)这样存储属性数量可变的 Java 对象,数据量大的时候 sql 语句怎么优化,或者有什么其他存储属性变量可变的数据存储检索方案吗

    16 条回复    2023-01-17 11:21:42 +08:00
    zhchyu999
        1
    zhchyu999  
       2023-01-15 22:42:42 +08:00
    mongodb ? es ?
    h0099
        2
    h0099  
       2023-01-15 22:48:41 +08:00
    https://en.wikipedia.org/wiki/Entity%E2%80%93attribute%E2%80%93value_model
    典型例子是 wordpress 中臭名昭著的 wp_postmeta 表 https://codex.wordpress.org/Database_Description

    但 EVA 性能也不如文档数据库(如 mongo )好,除非按 meta_key 分 partition 甚至分表
    h0099
        3
    h0099  
       2023-01-15 22:50:03 +08:00
    James0
        4
    James0  
       2023-01-16 02:21:44 +08:00
    为什么要用关系型,直接上 mongo 不行吗
    h0099
        5
    h0099  
       2023-01-16 07:33:17 +08:00
    > 像这篇文章( https://www.codenong.com/13466954/)

    有没有可能,这是又一个 stackexchange 机翻垃圾站:
    https://stackoverflow.com/questions/13466954/how-to-store-a-java-object-with-variable-number-of-attributes

    #4 @James0 换不换别的数据库主要看他愿不愿意,毕竟有学习迁移成本,比如得扔掉 sql 重新学习 mongo query lang (当然如果他本就不会手写 sql 一直都是靠 orm 抽象隔离那也没多少区别)
    wangxiaoaer
        6
    wangxiaoaer  
       2023-01-16 08:47:23 +08:00
    @James0 #4 如果系统里面 90 个实体都是常规关系型,剩下 10 个才是这种变化类的实体,全部换 mongo 也并不科学。

    这种我觉得有几种办法:

    1 机翻文提到那种方案,类 wordpress ,缺点是数据量上来后会爆炸。

    2 引入 ES ,把变化的属性信息塞进去,其他还放到 sql 中,然后查询层面做控制。

    3 变化信息通过 JSON 存储,选择支持 JSON 的关系型数据库,比如 PG 。
    h0099
        7
    h0099  
       2023-01-16 09:14:39 +08:00
    2. es 不也得重新学习他自己的查询语言而不是直接用基于的 sql orm
    3. mysql8 早就支持 json 列并对字段做索引了,当然如果 OP 所要存储的 json 的 root 层是字面量和 object/array 混合的

    ```
    0
    false
    NaN
    {a:1}
    [{a:1},undefined,{b,2}]
    null
    ```
    (以上都是合法 json )
    那就极难索引
    h0099
        8
    h0099  
       2023-01-16 09:17:57 +08:00
    1. 用 EAV 模型如果能把 meta_key (也就是 OP 要的动态字段名)给约束到已知范围从而改成 ENUM (本质 int )类型(但这就不动态)
    或是约束到定长 varchar (仍然动态)
    那就可以加索引
    但这索引的基数( index cardinality )会特别大导致查询计划优化器可能放弃使用他,对此可以添加 id 自然键构成 composite key ,如(post_id, meta_key)
    thetbw
        9
    thetbw  
       2023-01-16 09:43:54 +08:00
    单独整个 kv 的属性表可行不,主表只包含关键字段。其他都以 kv 形式存在另一张表
    h0099
        10
    h0099  
       2023-01-16 10:14:52 +08:00
    #9 @thetbw 这就是 EAV
    enjoychen0318
        11
    enjoychen0318  
       2023-01-16 11:18:22 +08:00
    shade
        12
    shade  
    OP
       2023-01-16 18:25:21 +08:00
    如果后期为了方便对商品进行协同过滤推荐,评分的指标个数不确定,评分矩阵如何存到数据库比较合适?
    Andy223
        13
    Andy223  
       2023-01-17 01:08:29 +08:00
    直接存 json 再搞个 inverted index 或者引入 es 不就完了?
    h0099
        14
    h0099  
       2023-01-17 03:33:22 +08:00   ❤️ 1
    #12 @shade 用 bitmask https://dev.mysql.com/doc/refman/8.0/en/set.html
    正好 /t/909074#r_12585697 里讨论过了
    kenvix
        15
    kenvix  
       2023-01-17 11:18:35 +08:00   ❤️ 1
    假定你一定要用关系型,并且排除关系型 KV 这种性能不高的做法...啥,矩阵?为什么不能用 postgres 的 array ?直接 flatten 后当 array 存不就行了?
    kenvix
        16
    kenvix  
       2023-01-17 11:21:42 +08:00
    再添加两个字段记录矩阵的 shape ,用的时候取回 array 再 reshape 就行了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5287 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 08:28 · PVG 16:28 · LAX 00:28 · JFK 03:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.