Sql 外键问题
我使用查询创建了一个表Sql 外键问题,sql,sql-server-2008,foreign-keys,Sql,Sql Server 2008,Foreign Keys,我使用查询创建了一个表 CREATE TABLE branch_dim ( branch_id numeric(18,0) NOT NULL, country_name varchar(30), island_name char(30), region_name varchar(30), branch_name varchar(30), region_manager varchar(30), marketing_manag
CREATE TABLE branch_dim (
branch_id numeric(18,0) NOT NULL,
country_name varchar(30),
island_name char(30),
region_name varchar(30),
branch_name varchar(30),
region_manager varchar(30),
marketing_manager varchar(30),
branch_manager varchar(30),
promoter_main varchar(30),
promoter_other varchar(30),
PRIMARY KEY (branch_id,island_name)
) ON branch_dim_scheme(island_name)
现在我有另一张桌子了
CREATE TABLE order_fact (
branch_id numeric(18,0) NOT NULL,
product_id numeric(18,0) NOT NULL,
order_id numeric(18,0) NOT NULL,
day_id numeric(18,0) NOT NULL,
FOREIGN KEY (branch_id) REFERENCES branch_dim (branch_id),
)
第一个查询中有分区,这就是为什么我有两个主键。现在,如果我运行第二个查询,就会得到错误
“没有主键或主键
引用表中的候选键
“branch_dim”与
外文中的参考列列表
键“FK_order_fac_branc_10234; AD”
可能有什么问题?您已将分支\u dim上的主键定义为由分支\u id和孤岛\u name组成的复合主键。创建订单事实时,您试图仅引用分支id作为外键。您已将分支id上的主键定义为由分支id和孤岛名称组成的复合主键。创建订单事实时,您试图仅引用分支id作为外键。您的表有一个复合主键:
CREATE TABLE branch_dim (
PRIMARY KEY (branch_id,island_name)
因此,对该表的任何外键引用也都必须将这两个元素用作其外键(您需要引用该键、整个键以及除键之外的任何内容-因此请帮助您编码:-):
建议:对于任何长度超过5个字符左右的字段,我将从不使用CHAR(x)
作为数据类型-这将创建一个长度始终为30个字符的字段-无论您是否在其中存储那么多字符。如果存储较少,则会使用空格填充该值,使其达到定义的长度(30个字符)
对于大于5个左右字符的任何内容,我建议使用始终而不是VARCHAR
numeric(18,0)
:对于ID
字段,我总是使用INT
——更好、更干净、更小、更简单 您的表有一个复合主键:
CREATE TABLE branch_dim (
PRIMARY KEY (branch_id,island_name)
因此,对该表的任何外键引用也都必须将这两个元素用作其外键(您需要引用该键、整个键以及除键之外的任何内容-因此请帮助您编码:-):
建议:对于任何长度超过5个字符左右的字段,我将从不使用CHAR(x)
作为数据类型-这将创建一个长度始终为30个字符的字段-无论您是否在其中存储那么多字符。如果存储较少,则会使用空格填充该值,使其达到定义的长度(30个字符)
对于大于5个左右字符的任何内容,我建议使用始终而不是VARCHAR
numeric(18,0)
:对于ID
字段,我总是使用INT
——更好、更干净、更小、更简单 您需要将branch_的主键设置为branch_id,并在island_name上添加索引。另外,您的分支ID真的是数字(18,0)吗?如果是这样的话,我会制作一个代理主键(可以是自动递增的,int或bigint,identity)
实际上,主键(以及聚集索引)非常宽。这会降低性能,我猜,在您的场景中,可能会将聚集索引分割(错误)。您需要将branch\u的主键设置为branch\u id,并在island\u name上添加索引。另外,您的分支ID真的是数字(18,0)吗?如果是这样的话,我会制作一个代理主键(可以是自动递增的,int或bigint,identity)
实际上,主键(以及聚集索引)非常宽。这会降低性能,我猜,在您的场景中,会将聚集索引(bad)分割成碎片。我通过将主键字段(分支id)设置为非聚集且唯一,并将孤岛名称字段设置为,从而解决了此问题,因此我只有一个主键,而我的分区键是孤岛名称。这解决了我的问题。谢谢大家的帮助。我解决了这个问题,将主键字段(分支id)设置为非聚集且唯一,并将孤岛名称字段设置为,因此我只有一个主键,分区键为孤岛名称。这解决了我的问题。谢谢大家的帮助。知道这是用于哪个数据库会很有帮助,因为答案可能会因特定的数据库而异。oops!!很抱歉这是sql server 2008。了解这是用于哪个数据库会很有帮助,因为答案可能会因特定的数据库而有所不同。oops!!很抱歉这是sql server 2008,我该怎么办?是否需要在第二个表中添加island_name字段?有没有其他方法可以在不将island_名称添加到第二个表中的情况下做到这一点?这是一个更大的数据库设计问题,需要真正理解您要做什么才能回答这个问题。然而,肯定有一些选择。首先,如果您真的要在branch_dim中唯一地标识一行,那么外键需要与主键相同,因此您需要添加一个类似的列来order_fact。如果branch_id足以准确标识branch_dim中的一行,则可以修改该表结构,使其仅使用branch_id作为主键。这确实取决于您计划如何构建和识别数据。我认为您应该花一些时间来了解索引、主键和外键以及聚集索引。这篇文章可能会有所帮助,但我最担心的是您正在使用numeric作为id。@Deepak-您只需要在
分支dim
中为分支id
添加一个唯一的约束。然后您应该能够创建order\u fact
@Dante617-实际上,表order\u fact是事实表,我正在使用外键链接维度表。我在branch\u dim上有一个分区,它是在branch\u dim.island\u name上完成的。有没有办法减少branch_dim(第一个表)中主键的数量?顺便说一下,我不应该丢失分区。那我该怎么办呢?是否需要在第二个表中添加island_name字段?有没有其他方法可以做到这一点,而不需要在secon中添加island_名称