我想考虑进一步简化这种方法。而不是定义代码(代码、代码键和代码值)的 3 个表,而只有一个包含代码类型和代码值的表呢?毕竟所有代码类型只是另一个代码列表。
也许像这样的表定义:
CREATE TABLE [dbo].[Code](
[CodeType] [int] NOT NULL,
[Code] [int] NOT NULL,
[CodeDescription] [nvarchar](40) NOT NULL,
[CodeAbreviation] [nvarchar](10) NULL,
[DateEffective] [datetime] NULL,
[DateExpired] [datetime] NULL,
CONSTRAINT [PK_Code] PRIMARY KEY CLUSTERED
(
[CodeType] ASC,
[Code] ASC
)
GO
可能存在 CodeType=0, Code=0 的根记录,它表示 CodeType 的类型。所有 CodeType 记录的 CodeType=0 和 Code>=1。以下是一些可能有助于澄清事情的示例数据:
SELECT CodeType, Code, Description FROM Code
Results:
CodeType Code Description
-------- ---- -----------
0 0 Type
0 1 Gender
0 2 Hair Color
1 1 Male
1 2 Female
2 1 Blonde
2 2 Brunette
2 3 Redhead
可以将检查约束添加到 Code 表中,以确保将有效的 CodeType 输入到表中:
ALTER TABLE [dbo].[Code] WITH CHECK ADD CONSTRAINT [CK_Code_CodeType]
CHECK (([dbo].[IsValidCodeType]([CodeType])=(1)))
GO
函数 IsValidCodeType 可以这样定义:
CREATE FUNCTION [dbo].[IsValidCodeType]
(
@Code INT
)
RETURNS BIT
AS
BEGIN
DECLARE @Result BIT
IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = 0 AND Code = @Code)
SET @Result = 1
ELSE
SET @Result = 0
RETURN @Result
END
GO
提出的一个问题是如何确保具有代码列的表具有该代码类型的正确值。这也可以通过使用函数的检查约束来强制执行。
这是一个 Person 表,它有一个性别列。最好的做法是使用代码类型的描述(在本例中为性别)后跟代码一词来命名所有代码列:
CREATE TABLE [dbo].[Person](
[PersonID] [int] IDENTITY(1,1) NOT NULL,
[LastName] [nvarchar](40) NULL,
[FirstName] [nvarchar](40) NULL,
[GenderCode] [int] NULL,
CONSTRAINT [PK_Person] PRIMARY KEY CLUSTERED ([PersonID] ASC)
GO
ALTER TABLE [dbo].[Person] WITH CHECK ADD CONSTRAINT [CK_Person_GenderCode]
CHECK (([dbo].[IsValidCode]('Gender',[Gendercode])=(1)))
GO
IsValidCode 可以这样定义:
CREATE FUNCTION [dbo].[IsValidCode]
(
@CodeTypeDescription NVARCHAR(40),
@Code INT
)
RETURNS BIT
AS
BEGIN
DECLARE @CodeType INT
DECLARE @Result BIT
SELECT @CodeType = Code
FROM dbo.Code
WHERE CodeType = 0 AND CodeDescription = @CodeTypeDescription
IF (@CodeType IS NULL)
BEGIN
SET @Result = 0
END
ELSE
BEGiN
IF EXISTS(SELECT * FROM dbo.Code WHERE CodeType = @CodeType AND Code = @Code)
SET @Result = 1
ELSE
SET @Result = 0
END
RETURN @Result
END
GO
当查询具有代码列的表时,可以创建另一个函数来提供代码描述。以下是查询 Person 表的示例:
SELECT PersonID,
LastName,
FirstName,
GetCodeDescription('Gender',GenderCode) AS Gender
FROM Person
这都是从防止数据库中查找表的泛滥并提供一个查找表的角度考虑的。我不知道这种设计在实践中是否会表现良好。