it-swarm.asia

متى تستخدم NULL ومتى تستخدم سلسلة فارغة؟

أنا مهتم بشكل رئيسي بـ MySQL و PostgreSQL ، ولكن يمكنك الإجابة عما يلي بشكل عام:

  • هل هناك سيناريو منطقي يكون من المفيد فيه تمييز سلسلة فارغة عن NULL؟
  • ما هي آثار التخزين المادي لتخزين سلسلة فارغة مثل ...

    • لا شيء؟
    • سلسلة فارغة؟
    • مجال آخر؟
    • بأي طريقة أخرى؟
87
Maniero

لنفترض أن السجل يأتي من نموذج لجمع معلومات الاسم والعنوان. عادةً ما يكون السطر 2 من العنوان فارغًا إذا لم يكن المستخدم يعيش في شقة. سلسلة فارغة في هذه الحالة صالحة تمامًا. أميل إلى استخدام NULL للإشارة إلى أن القيمة غير معروفة أو غير محددة.

لا أعتقد أن اختلاف التخزين الفعلي يستحق القلق في الممارسة العملية. كمديرين لقواعد البيانات ، لدينا أسماك أكبر بكثير لقليها!

67
Larry Coleman

أنا لا أعرف عن MySQL و PostgreSQL ، لكن دعني أعالج ذلك قليلاً بشكل عام.

يوجد DBMS واحد وهو Oracle الذي لا يسمح باختيار مستخدميه بين NULL و ''. يوضح هذا بوضوح أنه ليس من الضروري التمييز بين كليهما. هناك بعض العواقب المزعجة:

قمت بتعيين varchar2 إلى سلسلة فارغة مثل هذا:

Update mytable set varchar_col = '';

يؤدي ما يلي إلى نفس النتيجة

Update mytable set varchar_col = NULL;

ولكن لتحديد الأعمدة حيث تكون القيمة فارغة أو فارغة ، يجب عليك استخدامها

select * from mytable where varchar_col is NULL;

باستخدام

select * from mytable where varchar_col = '';

صحيحة نحويًا ، لكنها لا تُرجع أبدًا صفًا.

على الجانب الآخر ، عند ربط السلاسل في Oracle. يتم معاملة varchars NULL كسلاسل فارغة.

select NULL || 'abc' from DUAL;

العائد اي بي سي. سيعود DBMS أخرى NULL في هذه الحالات.

عندما ترغب في التعبير صراحةً عن تعيين قيمة ما ، يجب عليك استخدام شيء مثل "".

وعليك أن تقلق ما إذا كان تقليم نتائج فارغة لا فارغة

select case when ltrim(' ') is null then 'null' else 'not null' end from dual

نعم هو كذلك.

بالنظر الآن إلى DBMS حيث لا يتطابق "" مع NULL (مثل SQL-Server)

يعد العمل باستخدام '' أسهل بشكل عام وفي معظم الحالات لا توجد حاجة عملية للتمييز بين الاثنين. أحد الاستثناءات التي أعرفها ، هو عندما يمثل العمود الخاص بك بعض الإعدادات وليس لديك الإعدادات الافتراضية الفارغة لهم. عندما يمكنك التمييز بين '' و NULL ، يمكنك التعبير عن أن إعدادك فارغ وتجنب تطبيق الإعداد الافتراضي.

26
bernd_k

هذا يعتمد على المجال الذي تعمل عليه. NULL يعني عدم وجود قيمة (أي لا يوجد لا قيمة ) ، بينما تعني السلسلة الفارغة أن هناك قيمة السلسلة ذات طول صفري.

على سبيل المثال ، لنفترض أن لديك جدولًا لتخزين بيانات شخص ويحتوي على عمود Gender. يمكنك حفظ القيم مثل "ذكر" أو "أنثى". إذا كان المستخدم قادرًا على اختيار عدم تقديم بيانات النوع ، فيجب عليك حفظ ذلك كـ NULL (أي أن المستخدم لم يقدم القيمة) و لا سلسلة فارغة (نظرًا لعدم وجود جنس بقيمة '').

17
Gan

هناك شيء واحد يجب تذكره هو أنه عندما يكون لديك حقل غير مطلوب ، ولكن أي قيم موجودة يجب أن تكون فريدة سوف تتطلب منك تخزين القيم الفارغة مثل NULL. خلاف ذلك ، ستتمكن فقط من الحصول على Tuple واحد بقيمة فارغة في هذا المجال.

هناك أيضًا بعض الاختلافات مع الجبر الارتباطي وقيم NULL: NULL! = NULL ، على سبيل المثال.

10
Matthew Schinckel

يمكنك أيضًا أن تأخذ في الاعتبار نقد Date of NULL ومشكلات 3VL في SQL و Relational Theory (ونقد Rubinson لنقد Date ، Nulls ، Three-Valued Logic ، و Ambiguity in SQL: نقد تاريخ النقد ).

كلاهما يتم الرجوع إليهما ومناقشتهما باستفاضة في موضوع ذي صلة SO مؤشر ترابط --- خيارات لإزالة الأعمدة الفارغة من نموذج DB .

6
Abie

فكرة جديدة ، تأثير كبير على اختيارك NULL/NOT NULL إذا كنت تستخدم إطار عمل. أستخدم symfony كثيرًا واستخدام الحقول NULL يبسط بعضًا من التحقق من التعليمات البرمجية والبيانات عند معالجة البيانات.

إذا كنت لا تستخدم إطار عمل أو إذا كنت تستخدم عبارات SQL بسيطة ومعالجتها ، فسأختار أي خيار تشعر أنه أبسط في تتبعه. أنا أفضل بشكل عام NULL حتى لا تؤدي العبارات INSERT إلى الشعور بالتعب مع نسيان تعيين الحقول الفارغة على NULL.

4
Patrick

بعد العمل مع Oracle ( الذي لا يسمح لك بالتمييز ) توصلت إلى الاستنتاج التالي:

  • من وجهة نظر منطقية لا يهم. لا أستطيع حقًا التفكير في مثال مقنع حيث يضيف التفريق بين NULL وسلسلة بطول صفري أي قيمة في DBMS.

  • مما يلي: إما أن يكون لديك عمود NULLable لا يسمح بصفر len '' (حل Oracle-ish) أو عمود NOT NULL الذي يسمح بصفر len.

  • ومن تجربتي ، يجعل '' الكثير أكثر منطقية عند معالجة البيانات ، وعادةً ما ترغب في معالجة غياب سلسلة كسلسلة فارغة: تسلسل ، مقارنة ، إلخ.

ملاحظة: للرجوع إلى تجربة Oracle الخاصة بي: لنفترض أنك تريد إنشاء استعلام لطلب بحث. إذا كنت تستخدم '' ، يمكنك فقط إنشاء WHERE columnX = <searchvalue> وستعمل مع عمليات بحث المساواة. إذا كنت تستخدم NULL عليك القيام WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). باه! :-)

2
Martin

كما أنها تختلف عن منظور التصميم:

على سبيل المثال.

CREATE TABLE t (
    id INTEGER  NOT NULL,
    name CHARACTER(40),
    CONSTRAINT t_PK PRIMARY KEY (id)
);

CREATE UNIQUE INDEX t_AK1 ON t (name);

يشبه:

 \d t
          Table "public.t"
 Column |     Type      | Modifiers
--------+---------------+-----------
 id     | integer       | not null
 name   | character(40) |
Indexes:
    "t_pk" PRIMARY KEY, btree (id)
    "t_ak1" UNIQUE, btree (name)

يتيح إدراج بعض البيانات:

op=# insert into t(id, name ) values ( 1, 'Hello');
INSERT 0 1

op=# insert into t( id, name) values ( 2, '');
INSERT 0 1

op=# insert into t( id, name) values ( 3, '');

ERROR:  duplicate key value violates unique constraint "t_ak1"

الآن لنحاول مع null:

op=# insert into t( id, name) values (4, null );

INSERT 0 1

op=# insert into t( id, name) values (5, null);

INSERT 0 1

هذا مسموح.

Soooooo: القيم الخالية ليست سلاسل تافهة ولا العكس.

في صحتك

2
Guy Birkbeck

إذا تحدثنا عن النظرية ، فإن قواعد Codd تنص على أن RDBMS يجب أن يعامل قيم NULL بطريقة خاصة.

كيف يتم استخدام هذا بالضبط متروك لمهندسي قواعد البيانات ، اعتمادًا على المجال الفعلي - المهمة - المشروع - التطبيق - المنطقة.

1
noonex