【问题标题】:What would be the best table structure for variable amount of combination?对于可变数量的组合,最好的表结构是什么?
【发布时间】:2015-09-10 06:41:32
【问题描述】:

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

我正在处理一个项目,我需要保存由可变数量的其他值组合而成的值。

例如:

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

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

还有多列的解决方案(不需要时包含 null),但这不能很好地表示数据,过滤也会很困难。

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

您还有其他选择吗(除了切换到 nosql)?

【问题讨论】:

  • 采用联结表方法。它会胜过任何你认为你正在帮助数据库引擎的事情。并且数据的存储在同行看到时不会是一个面子时刻
  • 谢谢你的建议,我想我会去的。重复时mysql进程如何处理连接?我的意思是如果我的联结表包含外键,是否会为具有相同值的每一行处理连接数据“检索过程”?或者一旦检索到 FK 值,它就会被“缓存”或保存给具有相同值的其他行?

标签: mysql database database-design atomic


【解决方案1】:

这显示了使用连接表来避免将数据保存在逗号分隔的列表、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)

其他cmets

为了响应您的 cmets,数据仅在 mysql 具有最近使用 (MRU) 策略的情况下被缓存,不比任何缓存在内存中的数据与物理查找相比多或少。

B 目前可能不仅包含z,r,而且它可能也包含cA 一样,但这并不意味着存在重复。从架构中可以看出,没有父级可以复制其对子级的包含(或重复),这无论如何都是数据问题。

请注意,使用code 列可以轻松地在 cat 和 subcat 中进行 PK。不幸的是,这将导致广泛的索引,甚至更广泛的连接表的复合索引。这将大大减慢运营速度。尽管数据维护在视觉上可能更具吸引力,但我倾向于performance 而不是appearance

如果时间允许,我将在此答案中添加“哪些类别包含某个子类别”、删除等内容。

【讨论】:

    猜你喜欢
    • 2011-11-28
    • 2012-02-03
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多