3

我有一个简单的表:

Filepath | deleted | categories | description

我想将该表用于 Linq to SQL 实体模型。在模型上,该列pathnvarchar在数据库中是字符串)可以设置为主键,但 Visual Studio 表设计器并非如此。

路径是使一个文件唯一的原因,因此我必须确保表中没有重复的路径。如何做到这一点?谢谢你的时间。

4

2 回答 2

5

您可以使用 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 有类似的功能。(但是你可以有冲突,就像你可以使用几乎所有的哈希函数一样。)

于 2013-04-14T18:15:51.240 回答
3

正如 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).)

于 2013-04-14T18:13:19.863 回答