アイデア
Instagramで使用されているのと同じアプローチをお勧めします 。彼らの要件はあなたの要件に厳密に従っているようです。
生成されたIDは時間で並べ替え可能である必要があります(たとえば、写真IDのリストは、写真に関する詳細情報を取得せずに並べ替えることができます)IDは理想的には64ビットである必要があります(インデックスが小さく、Redisなどのシステムでのストレージが優れている場合)。可能な限り新しい「可動部品」をいくつか使用します。非常に少数のエンジニアでInstagramを拡張できた方法の大部分は、信頼できるシンプルでわかりやすいソリューションを選択することです。
彼らは、タイムスタンプに基づいて41ビット、データベースシャードに13ビット、自動インクリメント部分に10ビットのシステムを考案しました。シャードを使用していないように見えます。時間ベースのcopmonentには41ビット、ランダムに23ビットを選択できます。同時にレコードを挿入した場合、830万分の1の確率で競合が発生する可能性は非常に低くなります。しかし実際には、これにぶつかる可能性はほとんどありません。さて、いくつかのコードはどうですか:
IDの生成
START_TIME = a constant that represents a unix timestamp
def make_id():
'''
inspired by http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
'''
t = int(time.time()*1000) - START_TIME
u = random.SystemRandom().getrandbits(23)
id = (t << 23 ) | u
return id
def reverse_id(id):
t = id >> 23
return t + START_TIME
START_TIME
に注意してください 上記のコードでは、任意の開始時刻です。 time.time()* 1000を使用して値を取得し、それをSTART_TIME
として設定できます。
reverse_id
に注意してください 私が投稿した方法では、レコードがいつ作成されたかを知ることができます。その情報を追跡する必要がある場合は、別のフィールドを追加しなくても追跡できます。したがって、主キーは、ストレージを増やすのではなく、実際に保存することです!
モデル
これがモデルの外観です。
class MyClass(models.Model):
id = models.BigIntegerField(default = fields.make_id, primary_key=True)
djangoの外部でデータベースに変更を加える場合は、make_id
に相当するものを作成する必要があります。 SQL関数として
脚注として。これは、Mongodbが_ID を生成するために使用するアプローチにいくぶん似ています。 オブジェクトごとに。