colonne unique de type nvarchar

J'ai une table simple:

File : path | deleted | categories | description path | deleted | categories | description

Je veux utiliser la table pour un model d'entité Linq to SQL. Sur le model, ce path colonne (qui est une string, nvarchar dans la database) peut être défini en tant que key primaire, mais ce n'est pas le cas avec le concepteur de tables Visual Studio.

Un path est ce qui rend un file unique, donc je dois m'assurer qu'il n'y a pas de paths dupliqués dans la table. Comment y parvenir? Merci pour le time.

Vous rendez une colonne unique avec une contrainte UNIQUE, une contrainte NOT NULL UNIQUE ou une contrainte PRIMARY KEY dans SQL. Mais tous les dbms actuels que je peux penser au-dessus de ma tête ont une ou plusieurs ressortingctions sur la longueur d'un columnm qui peut être contraint de cette façon.

Cela signifie que vous avez un problème assez frappant pour le cas le plus général. Un path UNC sous Windows , par exemple, peut contenir environ 32 767 caractères.

Les systèmes Linux varient considérablement. 1024 et 4096 semblent communs, basé sur la search rapide de Google.

Je pense que vous allez devoir mettre une contrainte unique sur une key de substitution seulement . (Vous ne savez pas à quel point cela fait mal à un type de database de le dire.) Le problème est que vous pouvez imposer l'unicité à la mère porteuse, mais pas à la chose dont elle prend la place. Et la chose qui prend la place est la partie importante.

Un numéro d'identification ne fonctionnera pas dans le cas général; vous pourriez facilement vous refind avec {1, / etc / adjtime}, {2, / etc / adjtime}, {3, / etc / adjtime}. Vous avez besoin de quelque chose qui lie datatables réelles à la valeur de la key de substitution. Quelque chose comme hashbytes () fonctionnerait dans T-SQL; linq a des fonctions similaires. (Mais vous pouvez avoir des collisions, comme vous pouvez avec presque toutes les fonctions de hachage.)

Comme Martin l'a déjà expliqué, vous pouvez créer une key primaire tant que la valeur <= 450 caractères (ou 900 caractères, si vous êtes capable de contraindre datatables de sorte que les caractères Unicode ne soient pas autorisés). Cela fonctionne bien:

 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 ... ); 

Si un concepteur visuel dans une version non déclarée de Visual Studio vous permet de faire cela, je n'en ai aucune idée, mais vous n'avez pas besoin de créer vos tables en utilisant un concepteur visuel, n'est-ce pas?

Si le path est susceptible de dépasser 900 octets, vous ne pouvez pas en faire une key, désolé. Vous devrez utiliser une colonne IDENTITY , un autre substitut ou un hachage de la valeur du path à utiliser dans la key. Exemple d'un hachage qui prendra en charge un path de 4000 caractères – ce qui ne satisfait pas tous les cas d'utilisation potentiels, mais j'espère que vous n'avez pas besoin de dépasser 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'; 

Essayez de réexécuter l'insertion.

(Et encore, vous pouvez doubler les caractères 4000 à 8000 caractères si vous pouvez garantir qu'aucun path ne contiendra des caractères Unicode, dans ce cas, vous pouvez utiliser varchar(8000) au lieu de nvarchar(4000) .)