MySQL

数据库的动态列

动态列的几种设计思路 在需求开发过程中,我们有时会遇到一种场景:某个具体业务中的属性是动态的。在理想情况下,我们可以使用穷举法对所有可能的属性进行分析,然后进行分类,最终形成一套解决方案。然而,现实往往是骨感的,Leader和客户通常不会给我们这个时间。因此,我们需要探讨一些更为实际的解决方案。 一、使用数据库DDL进行动态创建 优点: 操作简单,只需通过SQL管理即可实现。 缺点: 不同情况下的动态字段增加会导致表结构膨胀。 在已有数据的表中修改字段容易导致锁表,影响性能。 二、使用数据库预留字段 优点: 与数据库无关,对业务侵入性小。 缺点: 扩展性差,超出预留字段范围后如何处理新字段? 可读性差,预留字段通常为attr1、attr2等,影响字段的可读性。 性能较低,为兼容多种数据类型,预留字段通常采用较长的文本数据类型存储,影响数据库性能。 三、使用数据库中的JSON数据类型 优点: 使用简单,绝大多数编程语言都支持JSON操作,方便快捷。 对于MySQL或PostgreSQL等数据库,已原生支持JSON字段,可基于JSON进行扩展查询。 JSON采用key:value形式存储数据,可避免字段可读性差的问题,通过规范命名提高可读性。 扩展性高,增加或删除字段实现简单,直接移除key即可,不影响表性能。 缺点: JSON字段查询操作与普通字段稍有差异,有一定复杂度。 JSON字段的索引性能有待提高。 四、使用NoSQL数据库 优点: 采用MongoDB等JSON数据库,可以快速扩展。 专业数据存储,查询等性能可针对优化,性能高。 缺点: 需要一定的学习成本。 综上所述,第一种和第二种方案若非必要,不建议采用。第三种方案在中小项目中能应对绝大多数需求。如果存储的数据较多且性能要求较高,可以考虑采用第四种方案或第三、四种方案相结合。 支持动态列的数据库 MariaDB 通过创建BLOB列(最大64k?),可以使用mariadb-dynamic-columns实现动态列。 示例: CREATE TABLE items ( id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, name varchar(100) NOT NULL, attributes BLOB ); 插入数据时使用特定函数(COLUMN_CREATE)指定动态列的数据结构,key/value形式: INSERT INTO items (name, attributes) VALUES ('MariaDB t-shirt', COLUMN_CREATE('colour','blue', 'size','XXL')), ('MariaDB t-shirt', COLUMN_CREATE('colour','blue', 'size','XL')), ('Samsung Galaxy S5', COLUMN_CREATE('colour','white', 'OS', 'Android', 'type', 'phone')), ('Samsung Galaxy Pro 3', COLUMN_CREATE('colour','white', 'size',8, 'OS', 'Android', 'resolution','1920x1200', 'type','tablet')); 查询时使用COLUMN_JSON函数,返回JSON格式的数据: SELECT name AS Item, COLUMN_JSON(attributes) AS 'Dynamic Columns' FROM items LIMIT 1; 使用COLUMN_LIST函数列举列中包含的属性,如colour、size: SELECT name AS Item, COLUMN_LIST(attributes) AS 'Attribute Names' FROM items; 查询动态列中具体的某个属性,如colour: SELECT name AS Item, COLUMN_GET(attributes, 'colour' AS CHAR) AS Colour FROM items; PostgreSQL 支持JSON数据类型,相比普通text文本字段类型,JSON数据类型强制要求列中每个存储的值都符合JSON格式规则。