数据模型,EAV的替代品

lyl*_*o0o 1 mysql database-design entity-attribute-value doctrine-orm

我有一个产品数据库,我想将文本,图像,视频附加到产品上。我还希望每个实体(文本,图像或视频)都具有标签,以便在应用程序上进行进一步的组织。

我想到使用此模型:

内容:

content_id|content_product_id|content_type|content_tag_id|content_url|content_title|content_text
Run Code Online (Sandbox Code Playgroud)

标签

tag_id|tag_name
Run Code Online (Sandbox Code Playgroud)

这意味着要使用Entity(content_product_id)-Attribute(content_tag_id)-值(content_url或content_title | content_text)模型。

看了很多书后,我知道使用这种建模模式(描述为数据库反模式,不可扩展并导致性能问题)是一个坏主意,您是否有其他替代方法的主意?

我想使用Doctrine ORM,并且我想找到一种可以轻松地与该数据映射器兼容的方法

Bil*_*win 5

我会为任何类型的内容创建一个通用表:

CREATE TABLE ProductContents(
  content_id INT AUTO_INCREMENT PRIMARY KEY,
  content_type INT NOT NULL
  -- other general attributes like when it was created, by whom, etc.
);
Run Code Online (Sandbox Code Playgroud)

对于每个文本,图像或视频,在此表中插入一行。如果使用自动递增主键,则此表负责生成ID号。

对于标签,现在您只需在ProductContent和标签之间建立多对多关系。这由相交表表示。

CREATE TABLE Tags (
  tag_id INT AUTO_INCREMENT PRIMARY KEY,
  tag TEXT NOT NULL
);

CREATE TABLE ProductContentTagged (
  content_id INT, 
  tag_id INT, 
  PRIMARY KEY (content_id, tag_id),
  FOREIGN KEY (content_id) REFERENCES ProductContents(content_id),
  FOREIGN KEY (tag_id) REFERENCES Tags(tag_id),
);
Run Code Online (Sandbox Code Playgroud)

然后,如果您具有每种内容类型的特定属性,请为每种类型创建辅助表,并且与内容表具有一对一的关系。

CREATE TABLE ProductContentTexts (
  content_id INT PRIMARY KEY,
  content TEXT NOT NULL,
  FOREIGN KEY (content_id) REFERENCES ProductContents(content_id)
);

CREATE TABLE ProductContentImages (
  content_id INT PRIMARY KEY,
  image_path TEXT NOT NULL,
  FOREIGN KEY (content_id) REFERENCES ProductContents(content_id)
);

CREATE TABLE ProductContentVideos (
  content_id INT PRIMARY KEY,
  video_path TEXT NOT NULL,
  FOREIGN KEY (content_id) REFERENCES ProductContents(content_id)
);
Run Code Online (Sandbox Code Playgroud)

请注意,这些辅助表没有自动递增列。他们不需要-他们将始终使用ProductContents表生成的值,并且您有责任插入该值。