数据库设计 - 我的数据应该有多精细?

时间:2014-07-21 18:17:14

标签: database database-design

假设我有一个应用程序向用户呈现座位表。

有三个座位区。

每个部分包含五行。

每行包含可变数量的席位。

每个座位都有自己的属性,其中包括与购买座位的客户的关联。

将数据建模到下表中是否有意义?

  • floor_plan
  • seating_section
  • seating_row
  • 客户

最终,需要对这些数据进行汇总,以使其对我的前端有意义且有用。如何将数据库中的数据组合成对给定视图有用且特定的东西?

此外,我还有更多关于类似数据库设计相关项目的问题。是否有任何好书可以为我提供坚实的基础?

1 个答案:

答案 0 :(得分:2)

从关系的角度来看,数据应该足够精细

  • dbms可以对其强制执行合理约束,
  • 客户端代码永远不必解析它。

假设只有一个场地(只有一个平面图),企业通常会根据其部分,行和数字来识别座位。多个平面图和多个场地的原则相同。

假设第1部分有3行,第2部分有5行,第3部分有4行。 (在PostgreSQL中测试过。)

create table sections (
  section_num integer primary key
    check (section_num between 1 and 3)
);

insert into sections values (1), (2), (3);

create table section_rows (
  section_num integer not null
    references sections (section_num),
  row_num integer not null
    check (row_num between 1 and 5),
  primary key (section_num, row_num)
);

insert into section_rows values
(1,1), (1,2), (1,3),
(2,1), (2,2), (2,3), (2,4), (2,5),
(3,1), (3,2), (3,3), (3,4);

create table seats (
  section_num integer not null,
  row_num integer not null,
  seat_num integer not null,
  primary key (section_num, row_num, seat_num),
  foreign key (section_num, row_num) 
    references section_rows (section_num, row_num)
);

insert into seats values
(1, 1, 1), (1, 1, 2), (1, 1, 3),
(1, 2, 1), (1, 2, 2), (1, 2, 3),
(1, 3, 1), (1, 3, 2), (1, 3, 3), (1, 3, 4),
(2, 1, 1), (2, 1, 2), (2, 1, 3),
(2, 2, 1), (2, 2, 2), (2, 2, 3),
(2, 3, 1), (2, 3, 2), (2, 3, 3), (2, 3, 4),
(2, 4, 1), (2, 4, 2), (2, 4, 3), (2, 4, 4),
(2, 5, 1), (2, 5, 2), (2, 5, 3), (2, 5, 4), (2, 5, 5),
(3, 1, 1), (3, 1, 2), (3, 1, 3),
(3, 2, 1), (3, 2, 2), (3, 2, 3),
(3, 3, 1), (3, 3, 2), (3, 3, 3), (3, 3, 4),
(3, 4, 1), (3, 4, 2), (3, 4, 3), (3, 4, 4);

最后一张桌子“座位”标识了场地中的每个座位。填充这三个表后,除非您撕掉座位或安装新座位,否则无需更改它们。

现在您可以将每个产品卖给顾客。

create table event_sales (
  -- Assumes an event identifier identifies the date and time as well
  -- as the event's name.
  event_id integer not null, -- references events (not shown)
  section_num integer not null,
  row_num integer not null,
  seat_num integer not null,
  customer_columns_go_here char(1) default 'x',
  primary key (event_id, section_num, row_num, seat_num),
  foreign key (section_num, row_num, seat_num) 
    references seats (section_num, row_num, seat_num)
);

insert into event_sales values
(1, 1, 1, 1, 'a'),
(1, 1, 1, 2, 'a'),
(1, 1, 1, 3, 'a'),
(1, 2, 2, 1, 'b'),
(2, 2, 1, 1, 'a'),
(2, 2, 1, 2, 'b'),
(2, 2, 1, 3, 'c'),
(2, 3, 2, 1, 'd');

所有这些表格至少为5NF。

活动1有哪些座位? (可能是座位申请的最常见查询。)

select *
from seats
except
(select section_num, row_num, seat_num from event_sales where event_id = 1)
order by section_num, row_num, seat_num;

数据库设计是一个比大多数人认为的更重要的话题。通过浏览几个网站,你不可能做到正确。学习时避免不良做法。我认为Bill Karwin的书SQL Antipatterns: Avoiding the Pitfalls of Database Programming可能是最好的。