سؤال

أقوم بتقديم تطبيق لتشغيله على كل من SQL Server و PostgreSQL ، لذلك أنا أطرح هذا السؤال حول كلاهما.

ماذا يحدث كلما قمت بإنشاء مفتاح أساسي فريد (باستخدام تسلسل أو نوع من النوع التلقائي) وضرب أكثر من 4 مليارات السجلات (32 بت)؟ أنا لا أقول أن طاولتنا سيكون لها 4 مليارات سجل ، بل تم إنشاء 4 مليارات سجلات بسبب الزيادات في التخلص فقط. لذلك حتى لو قمت بحذف 3.9 مليار من هذه السجلات ، فإن تسخيني لا تزال في نطاق 4 مليارات. إذن ماذا يحدث؟ هل تصل الدقة إلى 64 بت أم أنها تتدحرج إلى 0 أو فقط بصق خطأ فادح للغاية؟ هل يجب أن أشعر بالقلق من أنه حتى التخلص من 64 بت قد يفيض في النهاية أيضًا؟

أيضا ، كيف يمكنني محاربة هذا؟ هل هناك نوع من خيار التنظيف أو الأداة؟ هل يجب عليّ إنشاء شيء خاص بي كل عام أو نحو ذلك تمامًا إعادة بناء الطاولة للحصول على تسخين ثابتة؟ (وبالتالي تلمس الكثير من الجداول الأخرى التي تستخدم هذه التخلص هي مفاتيح أجنبية)

هل كانت مفيدة؟

المحلول

سوف PostgreSQL ، افتراضيا ، خطأ وليس الفائض:

# create sequence willyouwrap;
CREATE SEQUENCE
# select setval('willyouwrap', 9223372036854775807);
       setval        
---------------------
 9223372036854775807
(1 row)
# select nextval('willyouwrap');
ERROR:  nextval: reached maximum value of sequence "willyouwrap" (9223372036854775807)

من المستندات:

تعتمد التسلسلات على الحساب الكبير ، وبالتالي لا يمكن أن يتجاوز النطاق نطاق عدد صحيح من ثمانية بايت (-9223372036854775808 إلى 9223372036854775807). في بعض المنصات القديمة ، قد لا يكون هناك دعم للمترجم للأعداد الصحيحة ثمانية بايت ، وفي هذه الحالة تستخدم تسلسلات حساب عدد صحيح منتظم (المدى -2147483648 إلى +2147483647).

ومع ذلك ، يمكنك جعله دورة:

يسمح خيار الدورة بالتسلسل للالتفاف عندما يتم الوصول إلى MaxValue أو Minvalue من خلال تسلسل تصاعدي أو تنازلي على التوالي. إذا تم الوصول إلى الحد الأقصى ، فإن الرقم التالي الذي تم إنشاؤه هو Minvalue أو MaxValue ، على التوالي.

إذا لم يتم تحديد أي دورة ، فإن أي مكالمات إلى NextVal بعد أن تصل التسلسل إلى الحد الأقصى لقيمته ستعيد خطأ. إذا لم يتم تحديد أي دورة أو أي دورة ، فلا توجد دورة هي الافتراضي.

لا تقاتلها. اقض البايتات الإضافية والحفاظ على الأمور بسيطة. من المرجح أن تندم على إضافة طبقات إضافية من تعقيد المهام و/أو مهام الصيانة من امتلاك مساحة أكبر.

نصائح أخرى

على SQL Server: يعتمد ذلك على نوع العمود RID. يمكن أن تزيد الهوية الداخلية ، لكنها ستفشل في تعيين عمود Stoarge:

CREATE TABLE [t1] (
[tid] int IDENTITY (2147483647, 1) NOT NULL
  , name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')

هذا الخطأ يؤدي إلى:

Msg 8115, Level 16, State 1, Line 2
Arithmetic overflow error converting IDENTITY to data type int.
Arithmetic overflow occurred.

لكن عمودًا رقميًا يحتوي على مساحة تخزين كافية سوف يزداد على ما يرام:

CREATE TABLE [t1] (
[tid] numeric(38,0) IDENTITY (2147483647, 1) NOT NULL
  , name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')

وبالمثل ، سوف تتداخل Bigint في 2^^63-1:

CREATE TABLE [t1] (
[tid] bigint IDENTITY (9223372036854775807, 1) NOT NULL
  , name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')

لكن عمودًا رقميًا ذو تخزين كافٍ سينجح:

CREATE TABLE [t1] (
[tid] numeric(38,0) IDENTITY (9223372036854775807, 1) NOT NULL
  , name varchar(1)
) ON [PRIMARY]
GO
insert into t1(name) values('1')
insert into t1(name) values('1')
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top