0%

数据库中的竖表设计

在开发中,经常会遇到一些很松散的属性,只有很少的对象会有,属性间也没有什么联系。如果设计到同一张表中,属性间的相关性又不大,设计成独立表又会有太多的表,也不值得。这时候如果设计一张竖表就能很好的解决这样的问题。

比如说有一表User表,它的扩展属性的竖表可以这样设计:

1
2
3
4
5
6
7
8
9
10
11
mysql> desc UserAttribute;
+-----------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+----------------+
| userAttributeId | int(11) | NO | PRI | NULL | auto_increment |
| userId | int(11) | NO | | NULL | |
| attributeKey | varchar(20) | NO | | NULL | |
| attributeValue | varchar(50) | NO | | NULL | |
| createDate | datetime | NO | | NULL | |
| modifiedDate | datetime | YES | | NULL | |
+-----------------+-------------+------+-----+---------+----------------+

再在userIdattributeKey上面建立唯一索引,以提高效率,也保证数据完整性。其中attributeKey需要在代码中定义一个枚举,以说明其含义。使用时候时候定义一个addOrUpdate(int userId, String attributeKey, String attributeValue)方法和一个getValue(int userId, String attributeKey)方法。这样一个竖表的数据保存和读取功能就有了。

但有时候会有很多张表需要个辅助竖表,而且很张表里面的记录都不会很多。这时为每一张表设计一个竖表就又有点不值得了,可以设计一张通用的竖表来解决这个问题。这个表中用tableNamerecordId来确定一条记录。表的结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
mysql> desc EntityAttribute;
+-------------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+-------------+------+-----+---------+----------------+
| entityAttributeId | int(11) | NO | PRI | NULL | auto_increment |
| tableName | varchar(20) | NO | | NULL | |
| recordId | int(11) | NO | | NULL | |
| attributeKey | varchar(20) | NO | | NULL | |
| attributeValue | varchar(50) | NO | | NULL | |
| createDate | datetime | NO | | NULL | |
| modifiedDate | datetime | YES | | NULL | |
+-------------------+-------------+------+-----+---------+----------------+

这样就实现了所有表共用一个竖表来保存属性。只是与单独一张表的竖表相比,多出一个tableName也要用个枚举来维护。保存和读取的时候,都要把tableName当作参数传进去。

如果使用竖表的属性值进行查询的时候,性能会有很大问题,所以尽量只用竖表做单条数据的保存和显示。当然可以使用key-value的nosql数据库来实现这种功能。