2012-02-09 10 views
-2

私はC#に変換した以下のt-sqlコードを持っています。変換されたguid

DECLARE @guidRegular UNIQUEIDENTIFIER, @dtmNow DATETIME 

SELECT @guidRegular = '{5bf8e554-8dbc-4008-9d48-5c6e0a4d28d7}' 

SELECT @dtmNow = '2012-02-09 18:31:38' 


print (CAST(CAST(@guidRegular AS BINARY(10)) + CAST(@dtmNow AS BINARY(6)) AS UNIQUEIDENTIFIER)) 

私は(同じGUIDと日時を使用して)、コードの.NETバージョンを実行すると、私は別のGUIDを取得しますか?それは誰も助けることができるdatetime要素と関係があるように見えますか?

C#の拡張コード:

using system.data.linq; 
... 
... 

    public static class GuidExtensions 
    { 
     public static Guid ToNewModifiedGuid(this Guid guid) 
     { 
      var dateTime = new DateTime(2012,02,09,18,31,38); 
      var guidBinary = new Binary(guid.ToByteArray().Take(10).ToArray()); 
      var dateBinary = new Binary(BitConverter.GetBytes(dateTime.ToBinary()).ToArray().Take(6).ToArray()); 

      var bytes = new byte[guidBinary.Length + dateBinary.Length]; 
      Buffer.BlockCopy(guidBinary.ToArray(), 0, bytes, 0, guidBinary.ToArray().Length); 
      Buffer.BlockCopy(dateBinary.ToArray(), 0, bytes, guidBinary.ToArray().Length, dateBinary.ToArray().Length); 

      return new Guid(bytes); 
     } 
    } 
+4

なぜ、別の値として返すのではなく、GUIDの一部にdatetimeを追加するのですか? – 48klocs

+0

元のguidの最初の10バイトとdatetimeからの6バイトは、Guidの拡張として "modified guid"を作成するために使用されます... var modifiedGuid = Guid.NewGuid()。ToModifiedGuid() –

+2

As Philipと私は)、これはかなり頭のよいコードのにおいです。 GUIDを切り詰めてdatetimeにタックを付けても、グローバルに一意のIDはより多く、まあまあではありません。 – 48klocs

答えて

2

私はSQLおよび.NETは、日付/時刻の異なるバイナリ表現を持っているだろうと驚いていません。彼らがいたら私は驚くだろう。

C#コードは、DateTime構造体に、同じ値を再作成するために使用できる64ビット(8バイト)バイト配列に値をシリアル化するように要求しています。

あなたのsqlコードはSQLエンジンにdatetime(これも8バイト)の内部表現を取るように要求しています - スロー離れて2つ、結果を与える。だから、

  1. あなたは同じ値にしたい場合は、日時が/シリアル化され保存されているかの内部に頼る停止する必要があります。 .netとtsqlの両方で書くことができる反復可能なメソッドを使用して6バイトに変換してください。
  2. 空間的に一意の部分を表す6バイトのguidを削除し、時間で置き換えることを認識してください。したがって、GUIDの作成には、2回エンコードされた時刻があり、は非常にであり、重複するGUIDが作成される可能性が高くなります。

もちろん、これは「誰がそれをしたいのですか」というより明白な問題を無視します。私は、誰かが間違った問題を解決しようとしているという説がよりはっきりしているのではなく、本当に素晴らしいサブシステムだと考えています。

+0

ありがとうございます。sqlコードは、私が継承した既存のアプリケーションから来ており、コード内のコメントは、次の記事「主キーとしてのguidsのコスト」を指しています。http://www.informit.com/articles/article.asp?p=25862&redir = 1コードの置き換えが必要なようです...... –

0

オリジナルの記事はロジックに欠陥があります。著者は、Naturalキーと代理キーの両方について説明していますが、UUIDのRFCを使用してNaturalキーを作成できることを認識していません。もちろん、そのためには、デフォルトのマシン/時間ベースの関数を生成するのではなく、いくつかのソリューションドメイン情報に基づいてUUIDを生成するためのカスタム関数を作成する必要があります。

キーの生成を置き換える単一の機能を使用することは、これよりもはるかに意味があります。

関連する問題