2011-09-26 16 views
2

我正在製作當地的網吧列表網站,我想獲得一些關於我的數據庫結構的反饋。存儲無EAV的屬性/選項數據

這些咖啡館有一堆屬性,他們可以在任何選項上選擇一個或多個屬性。這是我如何計劃存儲他們的數據。

表: '網吧'

CREATE TABLE `cafes` (
    `cafe_id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    `cafe_types` text NOT NULL, 
    `location_types` text NOT NULL, 
    `amenities` varchar(255) NOT NULL, 
    `parking` varchar(255) NOT NULL, 
    PRIMARY KEY (`cafe_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ; 

表: 'cafes_option_map'

CREATE TABLE `cafes_option_map` (
    `map_id` int(11) NOT NULL AUTO_INCREMENT, 
    `column_name` varchar(30) NOT NULL, 
    `cafe_id` int(11) NOT NULL, 
    `name_id` int(11) NOT NULL, 
    PRIMARY KEY (`map_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

表: 'cafes_option_name'

CREATE TABLE `cafes_option_name` (
    `name_id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(255) NOT NULL, 
    PRIMARY KEY (`name_id`) 
) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

列cafe_types,location_types,設施和停車場多種選擇與許多「選項」。這些選項需要進行排序和過濾。

我的問題是:

  1. 是一個很好的,爲什麼存儲數據的?
  2. 會有更好的方法來做到這一點。

我的想法是,'咖啡館'表將包含逗號分隔的屬性名稱列表(如人類易讀),以最少的數據庫調用輕鬆顯示,然後還有用於篩選和排序查詢的選項表。

我可以爲表格創建一些示例數據,如果這樣更容易理解。

你會建議你如何存儲這些數據?我不想要一個EAV結構。

+0

''咖啡館'表將包含逗號分隔的屬性名稱列表'違反第一範式,因此是不好的設計。你希望你的屬性是動態的......不要這樣做。爲什麼不是EAV btw? –

+0

只是比EAV更糟的是CSV,不要這樣做,它會一次又一次地咬你。相信我在DB中的CSV是一場噩夢。 – Johan

回答

2

這是一個很好的爲什麼要存儲數據?

地獄不!

CSV是邪惡的
CSV無法以一種健全的方式進行索引。
在CSV上匹配很慢。
加入CSV是一場噩夢。
一旦你開始使用它們,你會變得粗體,因爲每當你需要寫一個新的查詢時,你就會開始拉出你的頭髮。

會有更好的方法來做到這一點。

EAV會比CSV好很多。

但我不想EAV

適合你,傷勢嚴重。 EAV只是一個停止差距的措施。
如果您想將n-attributes連接到n-cafes,那麼您有n-n關係,並且需要連接表。

table cafe 
------------ 
id integer PK autoincrement 
name 
address 

table cafe_type 
---------------- 
id integer PK autoincrement 
name 

table cafetype_link 
------------------- 
cafe_id integer 
cafe_type_id integer 
primary key PK (cafe_id, cafe_type_id) 

然後你做一個查詢上網吧類型,像這樣:

SELECT c.* 
FROM cafe c 
INNER JOIN cafetype_link cl ON (c.id = cl.cafe_id) 
INNER JOIN cafe_type ct ON (ct.id = cl.cafe_type_id) 
WHERE cafe_type.name = 'irish pub' 

這工作非常簡單,非常快。但它不如EAV那麼靈活。