テーブル内のテキストの組み合わせが既に存在するかどうかを調べるユニークなインデックスを作成したいと思います。 PostgreSQL
では、私はシンプルなCREATE INDEX
でこれをやった:SQL Serverで一意のMD5ハッシュインデックスを作成する方法は?
CREATE UNIQUE INDEX table_unique
ON cd.hdealerproductdata USING btree
(md5((((svId::text || manufacturer::text) || manufacturerreference::text) || path::text) || treetype::text) COLLATE pg_catalog."default")
TABLESPACE pg_default;
どのように私は(2016)SQL Serverでこれを行うことができますか?
ISNULL(HashBytes('MD5',CONVERT(VARCHAR(512),CONCAT(Manufacturer,ManufacturerReference))), 'null')
しかし、私はそれを言ってエラーを得た:私は(SSMSを使用して、テーブルdesigner->プロパティ - >計算列仕様)このような計算列を(およびそれに一意のインデックスを追加)を作成してみました検証することはできません。 https://docs.microsoft.com/en-us/sql/t-sql/functions/hashbytes-transact-sql
EDIT2:HashBytes
戻りvarbinary
タイプを私は計算列のデータ型を指定することはできません。
編集:私もHashBytes
とSHA-2を使用することができます。
後:
'Document' table
- Unable to modify table.
Implicit conversion from data type varchar to varbinary is not allowed. Use the CONVERT function to run this query.
EDIT3:私は挿入すると、私は持続し、一意のインデックスを作成した(計算列を作成しているときに、このためのスカラー関数を作成し、それを呼び出してしまいましたに)。
CREATE FUNCTION [dbo].[DocumentUniqueHash]
(
@DocumentTreeId bigint,
@Manufacturer nvarchar(255),
@ManufacturerReference nvarchar(255)
)
RETURNS varbinary(20)
WITH SCHEMABINDING
AS
BEGIN
-- Declare the return variable here
DECLARE @Result varbinary(20)
SELECT @Result = (hashbytes('SHA1',(CONVERT([nvarchar](max),@DocumentTreeId)[email protected])[email protected]))
-- Return the result of the function
RETURN @Result
END
と計算列と呼ばれる:([dbo].[DocumentUniqueHash]([DocumentTreeId],[Manufacturer],[ManufacturerReference]))
はまた、このような挿入ストアドプロシージャをした:
CREATE PROCEDURE DocumentInsert
@DocumentTreeId bigint,
@Manufacturer nvarchar(255),
@ManufacturerReference nvarchar(255),
@NewId bigint OUTPUT
AS
BEGIN
SELECT @NewId = Id FROM Document (NOLOCK)
WHERE UniqueHash = [dbo].[DocumentUniqueHash](@DocumentTreeId, @Manufacturer, @ManufacturerReference)
IF @NewId IS NULL
BEGIN
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT @NewId = Id FROM Document (NOLOCK)
WHERE UniqueHash = [dbo].[DocumentUniqueHash](@DocumentTreeId, @Manufacturer, @ManufacturerReference)
IF @NewId IS NULL
BEGIN
INSERT INTO Document (DocumentTreeId, Manufacturer, ManufacturerReference)
VALUES (@DocumentTreeId, @Manufacturer, @ManufacturerReference)
SELECT @NewId = SCOPE_IDENTITY()
END
COMMIT TRANSACTION
END
SELECT @NewId
END
GO
MD5の衝突が* *実証されている、私はそれはだかどうかを疑問視したいので、それは偶然に起こることは稀ですが、一意性を評価するための良い候補者です。列自体に対して独自の制約を適用することを除外したのはなぜですか? –
@Damien_The_Unbeliever列は長いvarcharsです( 'nvarchar(512)')。また、偶然に起こるmd5の衝突を本当に恐れているわけではありません(もしそれが意図的であれば、別の話題です)。私はsha1以上を使うことができました。それは本当に問題ではありません。 – appl3r
ユニークなハッシュを要求するのは意味がありません。ハッシュは完全にユニークではありません。それらは、迅速な比較とバケッティングに使用されるダイジェストです。彼らは意図的に損失の削減です。ユニークなインデックスが必要な場合は、別のものを作成する必要がありますが、ユースケースに基づいて、ユニークなインデックスのアイデアをあきらめるだけです。 (それはあなたが他の答えを聞くことに興味があると言いました) – AjahnCharles