【问题标题】:What if there are no possible primary keys in a table?如果表中没有可能的主键怎么办?
【发布时间】:2021-07-29 20:25:03
【问题描述】:

我必须为数据库设计一个宽表(timescaleDB,它将根据日期创建超表),但似乎没有可能的主键,即使我们正在谈论复合键。

| id | attribute1 | attribute2 | attribute3 | attribute4 |      date_time
| ---| ---------- | ---------- | ---------- | ---------- | -------------------
| P1 |     A      |     20     |    NULL    |    NULL    | 2021-01-01 00:00:00
| P1 |     B      |     10     |    NULL    |    NULL    | 2021-01-01 00:00:00
| P1 |    NULL    |    NULL    |    200     |    300     | 2021-01-01 00:00:00
| P2 |     C      |     25     |    NULL    |    NULL    | 2021-01-01 00:00:00
| P2 |    NULL    |    NULL    |    150     |    400     | 2021-01-01 00:00:00

问题是我们正在抓取描述 P1、P2 等整体的数据,并且仅描述 P1 的一部分(A 和 B 是 P1 的一部分)P2 (C) 等。 ..

有什么方法可以在不拆分表格的情况下完成这项工作?

【问题讨论】:

  • 添加一个作为唯一键的自增列或由序列驱动的列怎么样?
  • 让我印象深刻的是NULL 中的attribute1 隐含 意味着什么?或者P1 可以有多行(对于相同的日期时间),其中attribute1 是NULL? (如果 NULL 隐含意味着什么,请改用显式值,然后在键中使用该列)
  • 另外,你为什么反对有两张桌子?一个当attribute1 是NULL 时,一个当它不是?当attribute1 是NULL (反之亦然) 时,某些列总是NULL,这表明您正在将两个表组合在一起,这违反了正常的数据库设计实践。 .
  • Attribute1 和 Attribute2 对于 P1 将始终为 NULL,它们描述的是 A 和 B(它们属于 P1)。类似地,如果存在 A、B、C 等,attirubtes 和 attribute4 将始终为 NULL,因为这些属性正在描述 P1。就我个人而言,我也会选择单独的表格,只是周围有些人很难说服:)

标签: sql database-design


【解决方案1】:

您可以按照下面的设计。以下结构不会在数据库中存储任何null values

create table parenttable
(
  id int identity,
  Name nvarchar(10),
  primary key(id)
)

create table childtable
(
  id int identity,
  parent_id int,
  attribute nvarchar(50),
  valueattribute nvarchar(50),
  date_time datetime,
  primary key(id),
  foreign key(parent_id)references parenttable
);



insert into parenttable values
('P1'),
('P2')

insert into childtable values
(1,'attribute1','A','2021-01-01 00:00:00'),
(1,'attribute2','20','2021-01-01 00:00:00'),
(1,'attribute1','B','2021-01-01 00:00:00'),
(1,'attribute2','10','2021-01-01 00:00:00'),
(1,'attribute3','200','2021-01-01 00:00:00'),
(1,'attribute4','300','2021-01-01 00:00:00'),
(2,'attribute1','C','2021-01-01 00:00:00'),
(2,'attribute2','25','2021-01-01 00:00:00'),
(2,'attribute3','150','2021-01-01 00:00:00'),
(2,'attribute4','400','2021-01-01 00:00:00')

select *
from parenttable p join childtable c on p.id = c.parent_id

导致 dbfiddle:https://dbfiddle.uk

【讨论】:

    【解决方案2】:

    对于 P1,Attribute1 和 Attribute2 将始终为 NULL,它们描述的是 A 和 B(它们属于 P1)。同样,如果存在 A、B、C 等,attirubtes 和 attribute4 将始终为 NULL,因为这些属性描述的是 P1。

    您的问题陈述中没有足够的信息来回答您的问题。

    我没看懂上面的描述,但足以告诉我你需要应用函数依赖分析,并创建与“那些正在描述”一样多的表。

    attribute3 和attribute4 ...正在描述P1

    这表明您应该有一个表示 P1 事物的表,其中属性 3 和属性 4 作为列(最好具有有意义的名称)。

    围绕您正在建模的事物组织您的表格。

    • 查找对于特定事物不能为 NULL 的列。那些属于描述一种事物的表格。
    • 然后查找对于某种事物可能为 NULL 的列。这些可以是 NULL 列,也可以是共享相同键的单独表,具有可选的基数。
    • 没有其他类型的列。

    将列分组到表中并区分必要与非必要列后,您可以查看候选键的必填列。 总是这样一个键,即使它包括所有非 NULL 列。为什么?因为两个相同的行彼此无法区分。如果您认为需要两行这样的行,那么您真正需要的是 1 行和一个 quantity 列(不在键中),指示存在多少这样的行。

    【讨论】:

      猜你喜欢
      • 2019-12-24
      • 2019-11-03
      • 2012-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-28
      • 2015-08-11
      • 1970-01-01
      相关资源
      最近更新 更多