可变数量组合的最佳表格结构是什么?

时间:2015-09-10 06:41:32

标签: mysql database database-design atomicity

我需要一些建议来选择我的表结构。

我正在开展一个项目,我需要保存值,这些值是可变数量的其他值的组合。

例如:

A = b,c,d
B = z,r

我正在考虑将组合保存在列中的json对象中,但我担心它对于大请求来说可能很长并且不容易过滤。

还有一个具有多个列的解决方案(在不需要时包含null),但这不是数据的良好表示,过滤也很难。

最后我认为最好的关系是多对多,但加入可能太重了,是吗?

您是否看到任何其他替代方案(除了切换到nosql)?

1 个答案:

答案 0 :(得分:0)

这显示了使用Junction表来避免在逗号分隔的列表,json或其他至少在以下方面存在问题的机制中保存数据:

  • 表扫描(慢速,不使用快速索引)
  • 维护数据
  • 数据完整性

模式

create table cat
(   -- categories
    id int auto_increment primary key,
    code varchar(20) not null,
    description varchar(255) not null
);

create table subcat
(   -- sub categories
    id int auto_increment primary key,
    code varchar(20) not null,
    description varchar(255) not null
);

create table csJunction
(   -- JUNCTION table for cat / sub categories
    -- Note: you could ditch the id below, and go with composite PK on (catId,subCatId)
    -- but this makes the PK (primary key) thinner when used elsewhere
    id int auto_increment primary key,
    catId int not null,
    subCatId int not null,
    CONSTRAINT fk_csj_cat FOREIGN KEY (catId) REFERENCES cat(id),
    CONSTRAINT fk_csj_subcat FOREIGN KEY (subCatId) REFERENCES subcat(id),
    unique key (catId,subCatId) -- prevents duplicates
);


insert cat(code,description) values('A','descr for A'),('B','descr for B'); -- id's 1,2 respectively

insert subcat(code,description) values('b','descr for b'),('c','descr for c'),('d','descr for d');  -- id's 1,2,3
insert subcat(code,description) values('r','descr for r'),('z','descr for z'); -- id's 4,5

-- Note that due to the thinness of PK's, chosen for performance, the below is by ID
insert csJunction(catId,subCatId) values(1,1),(1,2),(1,3); -- A gets a,b,c
insert csJunction(catId,subCatId) values(2,4),(2,5);    -- B gets r,z

良好错误

以下错误是好的和预期的,数据保持清洁

insert csJunction(catId,subCatId) values(2,4); -- duplicates not allowed (Error: 1062)
insert csJunction(catId,subCatId) values(13,4); -- junk data violates FK constraint (Error: 1452)

其他评论

为了回应您的评论,数据仅在mysql具有最近使用(MRU)策略时缓存,不超过或少于内存中缓存的任何数据与物理查找。

B目前不仅可能包含z,r,而且 还可以包含cA也是如此并不意味着重复。并且如模式所示,没有父级可以复制其对子级的包含(或重复),这无论如何都会成为数据问题。

请注意,可以使用code列轻松地在cat和subcat中使用PK的路径。遗憾的是,这会导致广泛的索引,甚至是联结表的更复杂的索引。这将大大减缓运营速度。虽然数据维护在视觉上可能更具吸引力,但我任何时候都会performanceappearance

当时间允许显示“"什么类别包含某个子类别",删除等”时,我将添加到此答案