sql – 如何设计数据库模式以支持类别标记?

前端之家收集整理的这篇文章主要介绍了sql – 如何设计数据库模式以支持类别标记?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我试图像 Database Design for Tagging这样的东西,除了我的每个标签被分组.

例如,假设我有一个关于车辆的数据库.假设我们实际上不太了解车辆,所以我们不能指定所有车辆的列.因此,我们将“标记”车辆信息.

  1. 1. manufacture: Mercedes
  2. model: SLK32 AMG
  3. convertible: hardtop
  4.  
  5. 2. manufacture: Ford
  6. model: GT90
  7. production phase: prototype
  8.  
  9. 3. manufacture: Mazda
  10. model: MX-5
  11. convertible: softtop

现在,你可以看到所有的汽车都被标记了他们的制造和型号,但其他类别并不是全部匹配.请注意,一辆汽车只能有一个类别. IE浏览器.一辆汽车只能有一个制造商.

我想设计一个数据库支持所有梅赛德斯的搜索,或者能够列出所有的制造商.

我目前的设计是这样的:

  1. vehicles
  2. int vid
  3. String vin
  4.  
  5. vehicleTags
  6. int vid
  7. int tid
  8.  
  9. tags
  10. int tid
  11. String tag
  12. int cid
  13.  
  14. categories
  15. int cid
  16. String category

我拥有所有正确的主键和外键,除了我不能处理每个车只能有一个制造商的情况.还是我可以

我可以在vehicleTags中的复合主键中添加外键约束吗? IE浏览器.我可以添加一个约束,使得复合主键(vid,tid)只能在车辆标签中没有一行,才能添加到车辆标签,以便对于同一个vid,没有一个tid同样的cid?

我的猜测是否定的我认为这个问题的解决方案是添加一个cid列到vehicleTags,并使新的复合主键(vid,cid).它看起来像:

  1. vehicleTags
  2. int vid
  3. int cid
  4. int tid

这样可以防止汽车有两个制造商,但现在我已经复制了cid中的信息.

我的模式应该是什么?

在我之前的问题How do you do many to many table outer joins?中,Tom注意到我的数据库模式中的这个问题

编辑
我知道,在这个例子中,制造业应该是车载表中的一列,但是我们说你不能这样做.这个例子只是一个例子.

解决方法

这是 Entity-Attribute-Value设计的另一个变化.

更可识别的EAV表格如下所示:

  1. CREATE TABLE vehicleEAV (
  2. vid INTEGER,attr_name VARCHAR(20),attr_value VARCHAR(100),PRIMARY KEY (vid,attr_name),FOREIGN KEY (vid) REFERENCES vehicles (vid)
  3. );

有些人强制attr_name引用预定义属性名称的查找表,以限制混乱.

您所做的只是简单地将一个EAV表传播到三个表上,但不改进元数据的顺序:

  1. CREATE TABLE vehicleTag (
  2. vid INTEGER,cid INTEGER,tid INTEGER,cid),FOREIGN KEY (vid) REFERENCES vehicles(vid),FOREIGN KEY (cid) REFERENCES categories(cid),FOREIGN KEY (tid) REFERENCES tags(tid)
  3. );
  4.  
  5. CREATE TABLE categories (
  6. cid INTEGER PRIMARY KEY,category VARCHAR(20) -- "attr_name"
  7. );
  8.  
  9. CREATE TABLE tags (
  10. tid INTEGER PRIMARY KEY,tag VARCHAR(100) -- "attr_value"
  11. );

如果您要使用EAV设计,您只需要车辆标签和类别表.

  1. CREATE TABLE vehicleTag (
  2. vid INTEGER,-- reference to "attr_name" lookup table
  3. tag VARCHAR(100,-- "attr_value"
  4. PRIMARY KEY (vid,FOREIGN KEY (cid) REFERENCES categories(cid)
  5. );

但请记住,您正在将数据与元数据进行混合.您无法对数据模型应用某些限制.

>如何使其中一个类别成为强制性(常规列使用NOT NULL约束)?
>如何使用sql数据类型验证一些标签值?您不能,因为您为每个标签值使用长字符串.这个字符串对于您将来需要的每个标签都足够长吗?你不能告诉
>如何将一些标签限制为一组允许的值(传统的表使用查找表的外键)?这是你的“软顶”与“软顶”的例子.但是,您不能对标签列做出约束,因为该约束将适用于其他类别的所有其他标记值.您可以有效地将发动机尺寸和油漆颜色限制为“软顶”.

sql数据库与此模型不兼容.得到正确的是非常困难的,查询它变得非常复杂.如果您继续使用sql,那么您将更好地对表进行常规建模,每个属性有一列.如果您需要“子类型”,然后根据子类型(Class-Table Inheritance)定义下属表,否则使用Single-Table Inheritance.如果每个实体的属性有无限变化,则使用Serialized LOB.

为这些流体,非关系数据模型设计的另一种技术是语义数据库,存储数据于RDF,并与SPARQL进行了查询.一个免费的解决方案是Sesame.

猜你在找的MsSQL相关文章