0

複数の列を単一の列への外部キーとして疑っていました。例を挙げて説明しましょう。

例: 3 つのテーブルがあります。

会社 1 :Company_ID(guid) as Primary key, Address (varchar(25))

会社 2 :Company_ID(guid) as Primary key, Address (varchar(25))

従業員:Employee_ID(guid) as Primary key, Company_ID ( Foreign key referencing from Company1 and Company2)

ここで、Employee テーブルの Company_ID の外部キーは、2 つの異なるテーブルから取得されます。これは、SQL サーバー 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
4

1 に答える 1

0

あなたの気持ちは正しいです。。。これは「正しい」ものではありません。または、少なくとも、それは不十分な設計上の決定です。

ただし、外部キーの関係はおそらく複合キーです。一般に、これが参照するテーブルを指定する別の列があります。複雑なのは、これが「暗黙の」列である可能性があることです。したがって、1つのテーブルにUSアドレスがあり、他のテーブルにUS以外のアドレスがある場合、どちらのテーブルにも「IsUS」フラグがない可能性があります。ただし、米国のレコードは1つのテーブルを参照し、米国以外のレコードは別のテーブルを参照します。

もう1つの問題は、これらのキーがどのように維持されるかです。相互に依存する主キーを持つ2つのテーブルは本当に必要ありません。これを解決する一般的な方法は、2つのテーブルを1つに結合することです。

これは悪い考えですが、あなたはその構造に従わなければならないかもしれません。あなたがそれを変えることができるならば、あなたはそうすべきです。

于 2012-08-07T14:21:59.530 に答える