gri*_*esi 0 sql entity-attribute-value
我需要在关系数据库(MySQL)中建模人员数据库.
每个人都有财产.有一些属性只有1:1的关系(例如男性/女性)和其他有1:n关系的属性,如体育或语言(例如,一个人可能会打篮球和足球,会说英语和德语).另外这些1:n关系具有技能水平(例如专业,初学者).
目前我在问自己是否有比EAV模型更好的方法来模拟人 - 属性关系.我担心的主要是过滤那些有特殊属性的人更容易(例如所有演员都是男性和(专业打篮球或初学者)并且专业地讲英语.应该可以轻松添加新属性(这必须如果这需要由开发人员完成并且需要更改表,那就没关系了.但它不应该很难(例如修改sql语句,添加连接,添加数据库表/查找表) .
我会选择基于经典列的设计,在每个属性的单独列中的个人表中具有1:1属性.我不确定哪种是在这种设计中建模1:n关系的最佳方法.我想避免为每个1:n属性进行查找和单独的表.
最好的方法似乎仍然是以下EAV方法:
具有列id,名称的Persons表,例如
1 | Christian
具有列person_id,property,value,level的Properties表,例如:
1 | gender | male | 1 | sports | basketball | professional 1 | sports | football | beginner 1 | language | english | professional 1 | language | german | basic
如果您事先不了解数据模式,并且您不希望开发人员为每个新数据集修改系统,则EAV最合适.
从你所说的,这不是这里的情况.
EAV有许多缺点 - 例如,您不能依赖内置的关系模型来验证您的架构.因此,如果您的用户"Christian"没有指定其性别的值,则您的应用程序只需处理它 - 而在传统架构中,您有性别列,您声明"非null",并链接到"性别"查找表.对于大多数应用程序来说,这是一个大问题 - 在应用程序级别强制执行数据的有效性并非易事.
EAV的第二大缺点是易于使用SQL的查询变得非常复杂,性能降低得相当快,因为where子句中的每个项(例如"where gender ='m'")都成为子查询.
因此,我肯定会将您知道的架构数据建模为"传统"数据库.如果你想避免查找表,你可以 - 而不是拥有"性别"表的外键,你可以只依靠你的应用程序知道有效的选项是"m"和"f"(不要忘记处理这里可能发生的怪异 - "M"是有效的,而不是"m"吗?).
为了建模1:n关系,您可以创建一个单独的表,例如"person_sports",与"person"表具有外键关系.你可以,也许应该也有一个"体育"的查找表,在这种情况下你有一个多对多的关系.