Pyr*_*cal 15 sql tags schema foreign-keys entity-attribute-value
我正在尝试像Database Design for Tagging这样的东西,除了我的每个标签都按类别分组.
例如,假设我有一个关于车辆的数据库.假设我们实际上并不太了解车辆,因此我们无法指定所有车辆将具有的列.因此,我们将用信息"标记"车辆.
1. manufacture: Mercedes
   model: SLK32 AMG
   convertible: hardtop
2. manufacture: Ford
   model: GT90
   production phase: prototype
3. manufacture: Mazda
   model: MX-5
   convertible: softtop
现在您可以看到所有汽车都标有其制造和型号,但其他类别并不完全匹配.请注意,汽车只能拥有每个类别中的一个.IE浏览器.一辆汽车只能有一个制造商.
我想设计一个数据库来支持搜索所有梅赛德斯,或者能够列出所有制造商.
我目前的设计是这样的:
vehicles
  int vid
  String vin
vehicleTags
  int vid
  int tid
tags
  int tid
  String tag
  int cid
categories
  int cid
  String category
我有所有正确的主键和外键,除了我无法处理每辆车只能有一个制造商的情况.或者我可以吗?
我可以在vehicleTags中为复合主键添加外键约束吗?IE浏览器.我是否可以添加一个约束,使得复合主键(vid,tid)只能在vehicleTags中没有行时才添加到vehicleTags,这样对于同一个vid,还没有一个tid在同样的cid?
我的猜测是否定的.我认为这个问题的解决方案是向vehicleTags添加一个cid列,并创建新的复合主键(vid,cid).它看起来像:
vehicleTags
  int vid
  int cid
  int tid
这可以防止汽车有两个制造商,但现在我已经复制了tid在cid中的信息.
我的架构应该是什么?
在我之前的问题中,Tom在我的数据库模式中发现了这个问题,你如何做多对多表外连接?
编辑
 
我知道在示例制造中应该真的是车辆表中的一列,但是假设你不能这样做.这个例子只是一个例子.
Bil*_*win 15
这是实体 - 属性 - 值设计的另一个变体.
更易识别的EAV表如下所示:
CREATE TABLE vehicleEAV (
  vid        INTEGER,
  attr_name  VARCHAR(20),
  attr_value VARCHAR(100),
  PRIMARY KEY (vid, attr_name),
  FOREIGN KEY (vid) REFERENCES vehicles (vid)
);
有些人强制attr_name引用预定义属性名称的查找表,以限制混乱.
您所做的只是将EAV表分布在三个表上,但不改进元数据的顺序:
CREATE TABLE vehicleTag (
  vid         INTEGER,
  cid         INTEGER,
  tid         INTEGER,
  PRIMARY KEY (vid, cid),
  FOREIGN KEY (vid) REFERENCES vehicles(vid),
  FOREIGN KEY (cid) REFERENCES categories(cid),
  FOREIGN KEY (tid) REFERENCES tags(tid)
);
CREATE TABLE categories (
  cid        INTEGER PRIMARY KEY,
  category   VARCHAR(20) -- "attr_name"
);
CREATE TABLE tags (
  tid        INTEGER PRIMARY KEY,
  tag        VARCHAR(100) -- "attr_value"
);
如果你打算使用EAV设计,你只需要vehicleTags和categories表.  
CREATE TABLE vehicleTag (
  vid         INTEGER,
  cid         INTEGER,     -- reference to "attr_name" lookup table
  tag         VARCHAR(100, -- "attr_value"
  PRIMARY KEY (vid, cid),
  FOREIGN KEY (vid) REFERENCES vehicles(vid),
  FOREIGN KEY (cid) REFERENCES categories(cid)
);
但请记住,您正在将数据与元数据混合在一起.您将无法将某些约束应用于数据模型.
NOT NULL约束)?  tag列进行约束,因为该约束将适用于其他类别的所有其他标记值.您可以有效地将发动机尺寸和油漆颜色限制为"软顶".SQL数据库不适用于此模型.要做到正确是非常困难的,并且查询它变得非常复杂.如果继续使用SQL,则最好按常规方式对表进行建模,每个属性只有一列.如果您需要"子类型",则为每个子类型定义一个从属表(Class-Table Inheritance),否则使用Single-Table Inheritance.如果每个实体的属性具有无限的变化,则使用序列化LOB.
为这些流体非关系数据模型设计的另一种技术是语义数据库,它将数据存储在RDF中并使用SPARQL进行查询.一个免费的解决方案是芝麻.
| 归档时间: | 
 | 
| 查看次数: | 10598 次 | 
| 最近记录: |