我有一个简单的表:
File
:path | deleted | categories | description
我想将该表用于 Linq to SQL 实体模型。在模型上,该列path
(nvarchar
在数据库中是字符串)可以设置为主键,但 Visual Studio 表设计器并非如此。
路径是使一个文件唯一的原因,因此我必须确保表中没有重复的路径。如何做到这一点?谢谢你的时间。
我有一个简单的表:
File
:path | deleted | categories | description
我想将该表用于 Linq to SQL 实体模型。在模型上,该列path
(nvarchar
在数据库中是字符串)可以设置为主键,但 Visual Studio 表设计器并非如此。
路径是使一个文件唯一的原因,因此我必须确保表中没有重复的路径。如何做到这一点?谢谢你的时间。
您可以使用 SQL 中的 UNIQUE 约束、NOT NULL UNIQUE 约束或 PRIMARY KEY 约束来使列唯一。但是,我能想到的每一个当前的 dbms 对可以通过这种方式限制的 columnm 的长度都有一个或多个限制。
这意味着对于最一般的情况,你有一个相当引人注目的问题。例如, Windows 上的UNC 路径的长度约为 32,767 个字符。
Linux 系统差异很大。根据 Google 的快速研究,1024 和 4096 似乎很常见。
我认为您将不得不仅对代理键施加唯一约束。(您不知道这样说对数据库人员的伤害有多大。)问题是您可以对代理项强制唯一性,但不能对它所取代的东西强制执行唯一性。它取代的东西是重要的部分。
身份证号码在一般情况下不起作用;您可以轻松地以 {1, /etc/adjtime}, {2, /etc/adjtime}, {3, /etc/adjtime} 结束。您需要以某种方式将真实数据与代理键的值联系起来的东西。像hashbytes () 这样的东西会在 T-SQL 中“工作”;linq 有类似的功能。(但是你可以有冲突,就像你可以使用几乎所有的哈希函数一样。)
正如 Martin 已经解释的那样,您可以创建一个主键,只要值 <= 450 个字符(或 900 个字符,如果您能够限制数据以不允许使用 Unicode 字符)。这工作正常:
CREATE TABLE dbo.sample1
(
path NVARCHAR(450) NOT NULL PRIMARY KEY,
deleted BIT NOT NULL DEFAULT 0
-- ... other columns ...
);
CREATE TABLE dbo.sample2
(
path VARCHAR(900) NOT NULL PRIMARY KEY,
deleted BIT NOT NULL DEFAULT 0
-- ... other columns ...
);
某些未声明版本的 Visual Studio 中的某些可视化设计器是否允许您这样做,我不知道,但您不必使用某些可视化设计器创建表,对吗?
如果路径可能超过 900 字节,您不能将其设为密钥,抱歉。您必须使用IDENTITY
列、其他代理项或路径值的哈希值才能在键中使用。最多支持 4000 个字符的路径的哈希示例 - 不能满足所有潜在用例,但希望您不需要超过 4000:
CREATE TABLE dbo.sample3
(
[path] NVARCHAR(4000) NOT NULL,
pathhash AS CONVERT(VARBINARY(900), HASHBYTES('MD5', path))
PERSISTED PRIMARY KEY
);
INSERT dbo.sample3([path])
SELECT '\\some\share\x' + REPLICATE('x', 900) + '.gif'
UNION ALL SELECT '\\some\share\x' + REPLICATE('x', 900) + '.jpg';
尝试再次运行插入。
(同样,如果您可以保证没有路径包含 Unicode 字符,您可以将 4000 个字符加倍到 8000 个字符;在这种情况下,您可以使用varchar(8000)
代替nvarchar(4000)
.)