是否有好的情况不使用主键?

时间:2017-07-27 19:01:08

标签: sql sql-server database excel database-design

我目前正在做的事情涉及将多个Excel工作表转换为MS SQL Server数据库。其中大部分都是完全无关的,并且没有联系。有时,某些字段可能真正需要NULL条目。

在任何人开发数据库的经验中,您是否遇到过不使用主键的情况?

如果没有,在这种情况下我该怎么办?

5 个答案:

答案 0 :(得分:3)

在我看来,每个数据库表都应该有一个主键。这对于维护数据非常重要。您可以直接更新和删除数据库中的特定行。

某些数据库维护用户可见的内部行ID。这绝对是主键的可能替代方案,但我更喜欢在这些数据库中明确定义一个。

此外,整数标识主键执行以下操作:

  • 他们确定插入表格的顺序。
  • 它们是使用密钥的连接的略微优化。
  • 他们区分原本会重复的记录。
  • 它们提供了一种“水印”机制,用于跟踪最新更新的记录。

答案 1 :(得分:1)

主键的问题与表中的其他属性是否允许NULL并且与表是否需要链接到其他关系没有直接关系(尽管在这种链接中使用主键)没有直接关系。

相反,主键是关于建立和维护表中行所代表的对象的身份。在任何你需要知道真实世界的东西的应用程序中,#34;行引用,或者其中一行具有一组值并不是完全相同且可与具有相同值的另一行互换,那么您将需要一个主键。

当您的表仅使用 来生成单个源行没有意义的聚合结果时,您不需要主键。这确实涵盖了广泛的报告和分析情况。主键不会受到伤害,但在这种情况下毫无意义。

在分析情况下,您可能希望专门避免主键,其中数据是较大数据集的匿名提取。在这种情况下,没有主键有助于保证无法追溯到原始来源。

答案 2 :(得分:1)

如果您没有某种方法来唯一标识源数据中的每一行;您可能需要能够操作或检索数据中的特定行,然后您可以创建一个人工主键。例如。 ' Entry_ID'

我在你的例子中可以看到的主要问题是,如果你导入数据然后需要修改它。

说你导入

Name | Age | Favourite Colour
-----------------------------
Anne | 23  |  red
John | 34  |  blue
John | 34  |  blue

如果您要删除其中一个John, 34, blue,您会怎么做?嗯,有可能使用一些笨重的代码(我想你会有超过3列。)

Delete top (1) 
from testPK 
where name='john' 
and age=34 
and favouriteColour = 'blue';

但如果你有这个

Entry_ID | Name | Age | Favourite Colour
----------------------------------------
10001    |Anne | 23  |  red
10002    |John | 34  |  blue
10003    |John | 34  |  blue

然后它就像

一样简单
Delete from Table where Entry_ID = 10003

答案 3 :(得分:0)

根据我的经验,有很多情况你不需要使用PK。特别是如果要从外部源导入一些数据,则可以将批量中的所有内容导入到分段体系结构中,然后再处理数据和分发(ETL)。这在性能和重复数据删除,清理等方面都更好。

有时您也可以使用一些带有FREETEXT搜索的字典表,这也不需要PK。

话虽如此,在大多数情况下,您的生产表都有PK,原因很多:性能,组织等......

答案 4 :(得分:0)

在我早期的数据库开发经验中,我经常不使用主键,特别是从其他地方导入的数据,例如Excel工作表。并没有发生任何可怕的事。但回想起来,我正在玩火,很多事情可能容易出错。

因此,我认为这个问题的最佳答案是将其置于首位:是否曾经存在使用主键是糟糕主意的情况?我想不出主键会导致问题的情况。

至于转换Excel文件,我使用的方法是将Excel工作表直接导入为存储数据的表,直到我将其放入“真实”表中以便在数据库中使用。我使用主键IDENTITY字段+ Excel工作表中的所有字段创建“真实”表,并使用INSERT INTO传输数据。像这样:

CREATE TABLE real_table
    (
    Pkey int IDENTITY PRIMARY KEY not null
    , Column_A varchar(255) null
    , Column_B varchar(255) null
    )

INSERT INTO real_table(
    Column_A
    , Column_B)
select
    Column_A
    , Column_B
from Excel_import_table