【问题标题】:SQL Unique Value With Primary & Foreign Keys具有主键和外键的 SQL 唯一值
【发布时间】:2015-12-27 07:59:18
【问题描述】:

我很确定之前有人问过这个问题,但是使用 SQL 我试图只允许一个表使用主键和外键来具有唯一值。这可能听起来令人困惑,所以这些是我的 SQL 语句。

Folder表:

CREATE TABLE [dbo].[Folder] 
(
    [FolderID] VARCHAR(50) NOT NULL,
    [FolderURL] NCHAR(255) NOT NULL,
    [FolderTag] VARCHAR(50) NOT NULL,

    PRIMARY KEY CLUSTERED ([FolderURL] ASC),
    UNIQUE NONCLUSTERED ([FolderID] ASC)
);

Extension表:

CREATE TABLE [dbo].[Extension] 
(
    [ExtensionID] VARCHAR(10) NOT NULL,
    [FolderID] VARCHAR(50) NOT NULL,
    [LocationURL] VARCHAR(MAX) NOT NULL,

    PRIMARY KEY CLUSTERED ([ExtensionID] ASC),

    CONSTRAINT [fk_FolderID] 
        FOREIGN KEY ([FolderID])
        REFERENCES [dbo].[Folder]([FolderID]) ON DELETE CASCADE,
    CONSTRAINT uc_Extension UNIQUE ([ExtensionID], [FolderID]) 
);

Extension 表中,我希望使用[FolderID] & [ExtensionID] 使其具有唯一值。我首先尝试通过使用这两个值创建一个主键来实现这一点,然后我尝试了上面的当前语句。

编辑

我没有为我的要求提供足够的细节,下面是我想要创建的两个表的布局以及使用上述方法的结果。

Folder表:

----------------------------------------------------------
| Folder ID |        FolderURL        |  FolderTag       |
|-----------|-------------------------|------------------|
|   Home    | C:/users/test/          | Home Folder      |
| Downloads | E:/Donwloads            | Downloads Folder |
|   Music   | C:/users/test/music     | Music Folder     |
| Documents | C:/users/test/documents | Downloads Folder |
----------------------------------------------------------

Extension表:

---------------------------------------------------------
| Extension ID | FolderID  |        LocationURL         |
|--------------|-----------|----------------------------|
|    .jpg      | Downloads | C:/users/test/pictures     | = Pass 
|    .png      | Downloads | C:/users/test/pictures     | = Pass
|    .docx     | Documents | C:/users/test/BusinessDocs | = Pass
|    .mp3      |   Home    | C:/users/test/music        | = Pass
|    .jpg      |   Home    | C:/users/test/pictures     | = Fail
|    .mp3      | Downloads | C:/users/test/music        | = Fail
---------------------------------------------------------

从上面提供的表格布局中,您可以看到最后两个失败是因为 .mp3 ID 已经输入到表格中。我要问的是创建一个具有唯一主键的表,或者其他允许唯一ExtensionIDFolderID 的表,因此它将允许Extension 表中的最后两个值。

如果有人可以帮助我,我将不胜感激。

【问题讨论】:

  • 为什么不能将两者都设为主键?这是可以接受的。
  • 目前的方法有什么问题?使用FolderID,ExtensionID 上的唯一约束,您无法将重复项存储到该表中......所以基本上,这应该完全符合您的要求 - 不是吗??
  • 我认为我也可以接受,但似乎visual studio不接受,这可能是因为VS,但我不知道。我使用两者作为主键的语句是:CREATE TABLE [dbo].[Extension] ( [ExtensionID] VARCHAR (10) NOT NULL, [FolderID] VARCHAR (50) NOT NULL, [LocationURL] VARCHAR (MAX ) NOT NULL, 主键 ([ExtensionID], [FolderID]), 外键 ([FolderID]) 参考 [dbo].[Folder]([FolderID]) );但它似乎确实有效
  • 您没有回答我的问题:使用当前的方法,使用 UNIQUE 约束 - 您仍然可以将 重复数据 插入到您的表中吗?你不应该......
  • 您不应该使用这种设计添加重复项。您是否考虑过将 PKey 切换到 ID 字段? FKey 加入非 PKey 是不寻常的。有关更多信息,请参阅此问题:stackoverflow.com/questions/18435065/…

标签: sql-server foreign-keys unique primary-key


【解决方案1】:
CREATE TABLE [dbo].[Extension] 
(
    [ExtensionID] VARCHAR(10) NOT NULL,
    [FolderID] VARCHAR(50) NOT NULL,
    [LocationURL] VARCHAR(MAX) NOT NULL,

    PRIMARY KEY ([ExtensionID], [FolderID]),

    CONSTRAINT [fk_FolderID] 
        FOREIGN KEY ([FolderID])
        REFERENCES [dbo].[Folder]([FolderID]) ON DELETE CASCADE
);

这是完整的代码和输出。 SQLFiddle.com 不适合我;这是 PostgreSQL 语法。

CREATE TABLE Folder
(
    FolderID VARCHAR(50) NOT NULL,
    FolderURL NCHAR(255) NOT NULL,
    FolderTag VARCHAR(50) NOT NULL,

    PRIMARY KEY (FolderURL),
    UNIQUE (FolderID)
);

CREATE TABLE Extension 
(
    ExtensionID VARCHAR(10) NOT NULL,
    FolderID VARCHAR(50) NOT NULL,
    LocationURL VARCHAR(255) NOT NULL,

    PRIMARY KEY (ExtensionID, FolderID),

    CONSTRAINT fk_FolderID 
        FOREIGN KEY (FolderID)
        REFERENCES Folder(FolderID) ON DELETE CASCADE
);

insert into folder values
('Home', 'C:/users/test/', 'Home Folder'),
('Downloads', 'E:/Donwloads', 'Downloads Folder'),
('Music', 'C:/users/test/music', 'Music Folder'),
('Documents', 'C:/users/test/documents', 'Downloads Folder');

insert into Extension values
('.jpg', 'Downloads', 'C:/users/test/pictures'),
('.png', 'Downloads', 'C:/users/test/pictures'),
('.docx', 'Documents', 'C:/users/test/BusinessDocs'),
('.mp3', 'Home', 'C:/users/test/music'),
('.jpg', 'Home', 'C:/users/test/pictures'),
('.mp3', 'Downloads', 'C:/users/test/music');

select * from folder;
folderid folderurl foldertag -- 主页 C:/users/test/ 主文件夹 下载 E:/Donwloads 下载文件夹 音乐 C:/users/test/music 音乐文件夹 文件 C:/users/test/documents 下载文件夹
select * from extension;
extensionid folderid locationurl -- .jpg 下载 C:/users/test/pictures .png 下载 C:/users/test/pictures .docx 文档 C:/users/test/BusinessDocs .mp3 主页 C:/users/test/music .jpg Home C:/users/test/pictures .mp3 下载 C:/users/test/music

【讨论】:

  • 似乎不像我想要的那样工作。我有点希望我能更好地解释我想要什么。
  • " 似乎不像我想要的那样工作。" FWIW,这是非常无用的反馈。它完全像你你想要的那样工作。查看其他代码和输出。
  • 抱歉信息不足,在擦除整个数据库并测试您的数据库后,它按我需要的方式工作,我也谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-14
  • 1970-01-01
  • 2012-01-27
  • 2011-03-26
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多