Sql server 不同表中的多列作为一列的外键
我怀疑多个列是否是单个列的外键。让我举例说明 例:我有三张桌子: 公司1:Sql server 不同表中的多列作为一列的外键,sql-server,database,foreign-keys,primary-key,guid,Sql Server,Database,Foreign Keys,Primary Key,Guid,我怀疑多个列是否是单个列的外键。让我举例说明 例:我有三张桌子: 公司1:公司ID(guid)作为主键,地址(varchar(25)) 公司2:公司ID(guid)作为主键,地址(varchar(25)) 员工:员工ID(guid)作为主键,公司ID(外键引用公司1和公司2) 这里,Employee表中Company_ID的外键来自两个不同的表。 这适用于SQL server 2008。 我的问题是我觉得这是不对的。我从来没有在任何系统中这样做过,但我在一个示例中尝试过,它是有效的。我无法解释我
公司ID(guid)作为主键,地址(varchar(25))
公司2:公司ID(guid)作为主键,地址(varchar(25))
员工:员工ID(guid)作为主键,公司ID(外键引用公司1和公司2)
这里,Employee表中Company_ID的外键来自两个不同的表。
这适用于SQL server 2008。
我的问题是我觉得这是不对的。我从来没有在任何系统中这样做过,但我在一个示例中尝试过,它是有效的。我无法解释我自己,这里有什么地方不对劲,因为它工作得很好
我的假设是正确的还是请指导我?上述关系的缺陷是什么
USE [master]
GO
/****** Object: Database [Test] Script Date: 08/07/2012 14:32:32 ******/
CREATE DATABASE [Test] ON PRIMARY
( NAME = N'Test', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.FLEXIQUOTE\MSSQL\DATA\Test.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'Test_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10_50.FLEXIQUOTE\MSSQL\DATA\Test_log.ldf' , SIZE = 1024KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [Test] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [Test].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [Test] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [Test] SET ANSI_NULLS OFF
GO
ALTER DATABASE [Test] SET ANSI_PADDING OFF
GO
ALTER DATABASE [Test] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [Test] SET ARITHABORT OFF
GO
ALTER DATABASE [Test] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [Test] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [Test] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [Test] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [Test] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [Test] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [Test] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [Test] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [Test] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [Test] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [Test] SET DISABLE_BROKER
GO
ALTER DATABASE [Test] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [Test] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [Test] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [Test] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [Test] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [Test] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [Test] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [Test] SET READ_WRITE
GO
ALTER DATABASE [Test] SET RECOVERY SIMPLE
GO
ALTER DATABASE [Test] SET MULTI_USER
GO
ALTER DATABASE [Test] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [Test] SET DB_CHAINING OFF
GO
USE [Test]
GO
/****** Object: Table [dbo].[Table2] Script Date: 08/07/2012 14:32:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table2](
[Company2ID] [int] NOT NULL,
[COmpanyAddress] [nchar](10) NULL,
CONSTRAINT [PK_Table2] PRIMARY KEY CLUSTERED
(
[Company2ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table1] Script Date: 08/07/2012 14:32:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table1](
[Company1ID] [int] NOT NULL,
[CompanyName] [nchar](10) NULL,
CONSTRAINT [PK_Table1] PRIMARY KEY CLUSTERED
(
[Company1ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: Table [dbo].[Table3] Script Date: 08/07/2012 14:32:32 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Table3](
[EMployeeID] [int] NOT NULL,
[Company] [int] NULL,
CONSTRAINT [PK_Table3] PRIMARY KEY CLUSTERED
(
[EMployeeID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object: ForeignKey [FK_Table3_Table1] Script Date: 08/07/2012 14:32:32 ******/
ALTER TABLE [dbo].[Table3] WITH CHECK ADD CONSTRAINT [FK_Table3_Table1] FOREIGN KEY([Company])
REFERENCES [dbo].[Table1] ([Company1ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Table3] CHECK CONSTRAINT [FK_Table3_Table1]
GO
/****** Object: ForeignKey [FK_Table3_Table2] Script Date: 08/07/2012 14:32:32 ******/
ALTER TABLE [dbo].[Table3] WITH CHECK ADD CONSTRAINT [FK_Table3_Table2] FOREIGN KEY([Company])
REFERENCES [dbo].[Table2] ([Company2ID])
ON UPDATE CASCADE
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[Table3] CHECK CONSTRAINT [FK_Table3_Table2]
GO
你的感觉是对的。这是不“正确的”。或者,至少,这是一个糟糕的设计决策 但是,您的外键关系可能是一个复合键。一般来说,您将有另一列指定该表所引用的表。复杂的是,这可能是一个“隐式”列。因此,如果一个表有美国地址,而另一个表有非美国地址,那么两个表都可能没有“IsUS”标志。然而,美国记录将引用一个表,非美国记录将引用另一个表 另一个问题是如何维护这些密钥。您确实不希望有两个具有相互依赖的主键的表。解决这个问题的典型方法是将两个表合并为一个表
虽然这是一个坏主意,但您可能不得不接受这种结构。如果你能改变它,你应该改变。第一个问题是为什么有两个公司表?我举了一个简单的例子,因为我无法解释真实的情况。也就是说,在一些遗留系统中有两个类似的表,我现在无法更改:)您说外键在SQL Server 2008中“工作”,但我打赌您实际上没有在数据库中声明外键约束。这些不是
guid
s,正如大多数人理解的那样,它们是int
s。当您开始插入数据时,这个方案就崩溃了,除非您没有告诉我们,对于任何特定的ID,在公司
表中总会有行。