我一直在尝试不同的答案,而 Methai 的答案对我来说是最方便的。我当前的项目,虽然它使用 Doctrine 和 MySQL,但有很多松散的表。
以下是我对 Methai 解决方案的体验的结果:
创建实体表
DROP TABLE IF EXISTS entity;
CREATE TABLE entity (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(255),
author VARCHAR(255),
createdOn DATETIME NOT NULL
) Engine = InnoDB;
创建属性表
DROP TABLE IF EXISTS attribute;
CREATE TABLE attribute (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
type VARCHAR(255) NOT NULL
) Engine = InnoDB;
创建属性值表
DROP TABLE IF EXISTS attributevalue;
CREATE TABLE attributevalue (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
value VARCHAR(255) NOT NULL,
attribute_id INT UNSIGNED NOT NULL,
FOREIGN KEY(attribute_id) REFERENCES attribute(id)
) Engine = InnoDB;
创建 entity_attributevalue 连接表
DROP TABLE IF EXISTS entity_attributevalue;
CREATE TABLE entity_attributevalue (
entity_id INT UNSIGNED NOT NULL,
attributevalue_id INT UNSIGNED NOT NULL,
FOREIGN KEY(entity_id) REFERENCES entity(id),
FOREIGN KEY(attributevalue_id) REFERENCES attributevalue(id)
) Engine = InnoDB;
填充实体表
INSERT INTO entity
(title, author, createdOn)
VALUES
('TestFile', 'Joe', '2011-01-01'),
('LongNovel', 'Mary', '2011-02-01'),
('ShortStory', 'Susan', '2011-03-01'),
('ProfitLoss', 'Bill', '2011-04-01'),
('MonthlyBudget', 'George', '2011-05-01'),
('Paper', 'Jane', '2012-04-01'),
('Essay', 'John', '2012-03-01'),
('Article', 'Dan', '2012-12-01');
填充属性表
INSERT INTO attribute
(name, type)
VALUES
('ReadOnly', 'bool'),
('FileFormat', 'text'),
('Private', 'bool'),
('LastModified', 'date');
填充属性值表
INSERT INTO attributevalue
(value, attribute_id)
VALUES
('true', '1'),
('xls', '2'),
('false', '3'),
('2011-10-03', '4'),
('true', '1'),
('json', '2'),
('true', '3'),
('2011-10-04', '4'),
('false', '1'),
('ascii', '2'),
('false', '3'),
('2011-10-01', '4'),
('false', '1'),
('text', '2'),
('true', '3'),
('2011-10-02', '4'),
('false', '1'),
('binary', '2'),
('false', '3'),
('2011-10-20', '4'),
('doc', '2'),
('false', '3'),
('2011-10-20', '4'),
('rtf', '2'),
('2011-10-20', '4');
填充 entity_attributevalue 表
INSERT INTO entity_attributevalue
(entity_id, attributevalue_id)
VALUES
('1', '1'),
('1', '2'),
('1', '3'),
('1', '4'),
('2', '5'),
('2', '6'),
('2', '7'),
('2', '8'),
('3', '9'),
('3', '10'),
('3', '11'),
('3', '12'),
('4', '13'),
('4', '14'),
('4', '15'),
('4', '16'),
('5', '17'),
('5', '18'),
('5', '19'),
('5', '20'),
('6', '21'),
('6', '22'),
('6', '23'),
('7', '24'),
('7', '25');
显示所有记录
SELECT *
FROM `entity` e
LEFT JOIN `entity_attributevalue` ea ON ea.entity_id = e.id
LEFT JOIN `attributevalue` av ON ea.attributevalue_id = av.id
LEFT JOIN `attribute` a ON av.attribute_id = a.id;
id 标题作者创建在 entity_id 属性值_id id 值属性_id id 名称类型
1 TestFile Joe 2011-01-01 00:00:00 1 1 1 true 1 1 ReadOnly bool
1 TestFile Joe 2011-01-01 00:00:00 1 2 2 xls 2 2 文件格式文本
1 测试文件乔 2011-01-01 00:00:00 1 3 3 假 3 3 私有布尔
1 TestFile Joe 2011-01-01 00:00:00 1 4 4 2011-10-03 4 4 LastModified 日期
2 LongNovel Mary 2011-02-01 00:00:00 2 5 5 真 1 1 只读布尔
2 LongNovel Mary 2011-02-01 00:00:00 2 6 6 json 2 2 文件格式文本
2 LongNovel Mary 2011-02-01 00:00:00 2 7 7 真 3 3 私有布尔
2 LongNovel Mary 2011-02-01 00:00:00 2 8 8 2011-10-04 4 4 LastModified 日期
3 ShortStory 苏珊 2011-03-01 00:00:00 3 9 9 假 1 1 只读布尔
3 ShortStory Susan 2011-03-01 00:00:00 3 10 10 ascii 2 2 文件格式文本
3 ShortStory Susan 2011-03-01 00:00:00 3 11 11 假 3 3 私人布尔
3 ShortStory Susan 2011-03-01 00:00:00 3 12 12 2011-10-01 4 4 LastModified 日期
4 利润损失法案 2011-04-01 00:00:00 4 13 13 false 1 1 ReadOnly bool
4 利润损失法案 2011-04-01 00:00:00 4 14 14 文本 2 2 文件格式文本
4 利润损失法案 2011-04-01 00:00:00 4 15 15 true 3 3 Private bool
4 损益法案 2011-04-01 00:00:00 4 16 16 2011-10-02 4 4 LastModified date
5 MonthlyBudget George 2011-05-01 00:00:00 5 17 17 false 1 1 ReadOnly bool
5 MonthlyBudget George 2011-05-01 00:00:00 5 18 18 二进制 2 2 文件格式文本
5 MonthlyBudget George 2011-05-01 00:00:00 5 19 19 false 3 3 Private bool
5 MonthlyBudget George 2011-05-01 00:00:00 5 20 20 2011-10-20 4 4 LastModified 日期
6 纸简 2012-04-01 00:00:00 6 21 21 二进制 2 2 文件格式文本
6 纸简 2012-04-01 00:00:00 6 22 22 假 3 3 私有布尔
6 论文 Jane 2012-04-01 00:00:00 6 23 23 2011-10-20 4 4 LastModified 日期
7 随笔 John 2012-03-01 00:00:00 7 24 24 二进制 2 2 文件格式文本
7 随笔约翰 2012-03-01 00:00:00 7 25 25 2011-10-20 4 4 LastModified 日期
8 文章 Dan 2012-12-01 00:00:00 NULL NULL NULL NULL NULL NULL NULL NULL
数据透视表
SELECT e.*,
MAX( IF(a.name = 'ReadOnly', av.value, NULL) ) as 'ReadOnly',
MAX( IF(a.name = 'FileFormat', av.value, NULL) ) as 'FileFormat',
MAX( IF(a.name = 'Private', av.value, NULL) ) as 'Private',
MAX( IF(a.name = 'LastModified', av.value, NULL) ) as 'LastModified'
FROM `entity` e
LEFT JOIN `entity_attributevalue` ea ON ea.entity_id = e.id
LEFT JOIN `attributevalue` av ON ea.attributevalue_id = av.id
LEFT JOIN `attribute` a ON av.attribute_id = a.id
GROUP BY e.id;
id 标题 作者 createdOn ReadOnly FileFormat Private LastModified
1 TestFile 乔 2011-01-01 00:00:00 真 xls 假 2011-10-03
2 LongNovel Mary 2011-02-01 00:00:00 true json true 2011-10-04
3 ShortStory 苏珊 2011-03-01 00:00:00 假 ascii 假 2011-10-01
4 利润损失法案 2011-04-01 00:00:00 false text true 2011-10-02
5 MonthlyBudget George 2011-05-01 00:00:00 false binary false 2011-10-20
6 纸简 2012-04-01 00:00:00 NULL 二进制 false 2011-10-20
7 随笔约翰 2012-03-01 00:00:00 NULL 二进制 NULL 2011-10-20
8 文章 Dan 2012-12-01 00:00:00 NULL NULL NULL NULL