私はさまざまな答えを試してきましたが、メタイの答えが私にとって最も便利でした。私の現在のプロジェクトは、MySQL で Doctrine を使用していますが、かなりの数のルーズ テーブルがあります。
以下は、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 タイトル 作成者 createdOn entity_id attributevalue_id ID 値 attribute_id ID 名前 タイプ
1 TestFile Joe 2011-01-01 00:00:00 1 1 1 true 1 1 ReadOnly ブール
1 TestFile Joe 2011-01-01 00:00:00 1 2 2 xls 2 2 FileFormat テキスト
1 TestFile Joe 2011-01-01 00:00:00 1 3 3 false 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 true 1 1 ReadOnly ブール
2 LongNovel Mary 2011-02-01 00:00:00 2 6 6 json 2 2 FileFormat テキスト
2 LongNovel Mary 2011-02-01 00:00:00 2 7 7 true 3 3 Private bool
2 LongNovel Mary 2011-02-01 00:00:00 2 8 8 2011-10-04 4 4 最終更新日
3 ShortStory スーザン 2011-03-01 00:00:00 3 9 9 false 1 1 ReadOnly bool
3 ShortStory Susan 2011-03-01 00:00:00 3 10 10 ascii 2 2 FileFormat テキスト
3 ShortStory スーザン 2011-03-01 00:00:00 3 11 11 false 3 3 Private bool
3 ShortStory Susan 2011-03-01 00:00:00 3 12 12 2011-10-01 4 4 最終更新日
4 ProfitLoss Bill 2011-04-01 00:00:00 4 13 13 false 1 1 ReadOnly bool
4 ProfitLoss Bill 2011-04-01 00:00:00 4 14 14 テキスト 2 2 FileFormat テキスト
4 ProfitLoss Bill 2011-04-01 00:00:00 4 15 15 true 3 3 プライベート bool
4 ProfitLoss Bill 2011-04-01 00:00:00 4 16 16 2011-10-02 4 4 LastModified date
5 MonthlyBudget ジョージ 2011-05-01 00:00:00 5 17 17 false 1 1 ReadOnly bool
5 MonthlyBudget ジョージ 2011-05-01 00:00:00 5 18 18 バイナリ 2 2 FileFormat テキスト
5 MonthlyBudget ジョージ 2011-05-01 00:00:00 5 19 19 false 3 3 Private bool
5 MonthlyBudget ジョージ 2011-05-01 00:00:00 5 20 20 2011-10-20 4 4 LastModified date
6 Paper Jane 2012-04-01 00:00:00 6 21 21 バイナリ 2 2 FileFormat テキスト
6 Paper Jane 2012-04-01 00:00:00 6 22 22 false 3 3 Private bool
6 紙ジェーン 2012-04-01 00:00:00 6 23 23 2011-10-20 4 4 LastModified date
7 エッセイ ジョン 2012-03-01 00:00:00 7 24 24 バイナリ 2 2 FileFormat テキスト
7 エッセイ ジョン 2012-03-01 00:00:00 7 25 25 2011-10-20 4 4 LastModified date
8 Article 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 title author createdOn ReadOnly FileFormat Private LastModified
1 TestFile Joe 2011-01-01 00:00:00 true xls false 2011-10-03
2 LongNovel Mary 2011-02-01 00:00:00 true json true 2011-10-04
3 ShortStory Susan 2011-03-01 00:00:00 false ascii false 2011-10-01
4 ProfitLoss Bill 2011-04-01 00:00:00 false テキスト true 2011-10-02
5 MonthlyBudget ジョージ 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 Article Dan 2012-12-01 00:00:00 NULL NULL NULL NULL