【问题标题】:Efficient way to store list of partitioned sets in SQL在 SQL 中存储分区集列表的有效方法
【发布时间】:2015-04-15 10:49:43
【问题描述】:

我有一个事物列表,每个事物都有多个名称(称这些为 N)和多个属性 (A)。一个例子是带有昵称的宠物列表:

{ Charles } <-> { goldfish }
{ Fluffy, Mr. Fluffs, Señor Fluffs} <-> { gato, cat, chat, feline }
{ Fido, Buster } <-> {dog, Labrador mix, mutt, brown-haired, chien}

我可能有很多这些,其中大多数可能在 N 和 A 中只有一两个条目,但原则上可能有大量条目。我还需要存储关于每条记录的少量数据,例如每只宠物的年龄和出生地。

我需要按顺序检索每个事物,并让该事物的每个集合中的所有数据都易于访问。

您能否提出一种策略性的方法来构建我的数据库表?具有逗号分隔值的两个字段很诱人,但我肯定可以做得更好,对吧?我有点卡住了。

提前致谢,

马克 C.

【问题讨论】:

  • 所有可能属性的列表是否可预测?
  • 不是特别 - 我们不会在每一个甚至大多数记录上都有一个品种和一个法语名字。它们在性格和重量上相当相似。另一个例子可能是(与宠物不同)作为风味的属性,所以{葡萄、樱桃、草莓}是一个,{巧克力、香草、菠萝、覆盆子、橙子}是另一个。

标签: mysql sql database database-design database-schema


【解决方案1】:

您想要一个由三张表组成的规范化数据库:一张用于宠物,一张带有名称,一张带有属性。在 MySQL 中:

create table pet (
    id int primary key,
    dateOfBirth date,
    placeOfBirth varchar(50)
);

create table name (
    id int references pet (id),
    name varchar(50),
    primary key (id , name)
);

create table attribute (
    id int references pet (id),
    attribute varchar(50),
    primary key (id , attribute)
);

insert into pet (id) values (1);
insert into pet (id) values (2);
insert into pet (id) values (3);

insert into name (id,name) values (1,'Charles');
insert into name (id,name) values (2,'Fluffy');
insert into name (id,name) values (2,'Mr. Fluffs');
insert into name (id,name) values (2,'Señor Fluffs');
insert into name (id,name) values (3,'Fido');
insert into name (id,name) values (3,'Buster');

insert into attribute (id,attribute) values (1,'goldfish');
insert into attribute (id,attribute) values (2,'gato');
insert into attribute (id,attribute) values (2,'cat');
insert into attribute (id,attribute) values (2,'chat');
insert into attribute (id,attribute) values (2,'feline');
insert into attribute (id,attribute) values (3,'dog');
insert into attribute (id,attribute) values (3,'Labrador mix');
insert into attribute (id,attribute) values (3,'mutt');
insert into attribute (id,attribute) values (3,'brown-haired');
insert into attribute (id,attribute) values (3,'chien');

如果你想要一个聚合,你可以像这样查询这些表:

select 
    group_concat(distinct name
        order by name),
    group_concat(distinct attribute
        order by attribute)
from
    pet
        inner join
    name USING (id)
        inner join
    attribute USING (id)
group by id;

【讨论】:

  • name 不能只是pet 表中的一列吗?
  • 如果宠物只有一个名字,是的。但是这里有多个名称。
猜你喜欢
  • 2014-02-09
  • 1970-01-01
  • 1970-01-01
  • 2020-11-12
  • 2014-01-29
  • 2017-01-28
  • 2017-04-24
  • 2018-07-19
  • 1970-01-01
相关资源
最近更新 更多