Khi nào nên sử dụng NULL và khi nào nên sử dụng một chuỗi rỗng?


82

Tôi quan tâm chủ yếu đến MySQL và PostgreSQL, nhưng bạn có thể trả lời chung như sau:

  • Có một kịch bản logic nào trong đó sẽ hữu ích khi phân biệt một chuỗi rỗng với NULL không?
  • Điều gì sẽ có ý nghĩa lưu trữ vật lý để lưu trữ một chuỗi trống là ...

    • VÔ GIÁ TRỊ?
    • Chuỗi rỗng?
    • Một lĩnh vực khác?
    • Bất kỳ cách nào khác?

Câu trả lời:


67

Hãy nói rằng hồ sơ xuất phát từ một hình thức để thu thập thông tin tên và địa chỉ. Dòng 2 của địa chỉ thường sẽ trống nếu người dùng không sống trong căn hộ. Một chuỗi rỗng trong trường hợp này là hoàn toàn hợp lệ. Tôi có xu hướng thích sử dụng NULL có nghĩa là giá trị không xác định hoặc không được cung cấp.

Tôi không tin rằng sự khác biệt lưu trữ vật lý là đáng lo ngại trong thực tế. Là quản trị viên cơ sở dữ liệu, chúng tôi có cá lớn hơn nhiều để chiên!


2
+1 rất ít dba từng cần lo lắng về sự khác biệt về tốc độ / kích thước của việc sử dụng NULLhay không
Patrick

28
Đồng ý ... Tôi cố gắng dự trữ NULL cho 'không biết' ... chuỗi trống là 'chúng tôi biết nó nên trống'. Nó đặc biệt hữu ích khi dữ liệu của bạn đến từ nhiều nguồn
Joe

6
Nổi bật - Không biết NULL, Chuỗi rỗng đã được chỉ định.
ScottCher

@Larry tác động hiệu suất là gì? Làm thế nào để hiệu suất thay đổi với các bảng của nhiều cols so với các bảng của nhiều hàng?
Shimmy

Tôi đồng ý rằng nếu có sự phân biệt giữa không có giá trị được đưa ra và một chuỗi trống trong tập dữ liệu của bạn thì bạn nên sử dụng chúng một cách thích hợp, nhưng cá nhân nếu tôi không cần sự phân biệt đó với dữ liệu của mình thì tôi luôn sử dụng một chuỗi trống, hoàn toàn vì tôi tìm thấy kết quả truy vấn từ máy khách MySQL trên dòng lệnh có thể sạch hơn để xem xét với các chuỗi trống thay vì nhiều NULL
RTF

25

Tôi không biết về MySQL và PostgreSQL, nhưng hãy để tôi xử lý vấn đề này một chút nói chung.

Có một DBMS là Oracle không cho phép chọn người dùng giữa NULL và ''. Điều này chứng tỏ rõ ràng rằng không cần thiết phải phân biệt giữa cả hai. Có một số hậu quả khó chịu:

Bạn đặt một varchar2 thành một chuỗi rỗng như thế này:

Update mytable set varchar_col = '';

những điều sau đây dẫn đến kết quả tương tự

Update mytable set varchar_col = NULL;

Nhưng để chọn các cột có giá trị trống hoặc NULL, bạn phải sử dụng

select * from mytable where varchar_col is NULL;

Sử dụng

select * from mytable where varchar_col = '';

là đúng về mặt cú pháp, nhưng nó không bao giờ trả về một hàng.

Mặt khác, khi nối các chuỗi trong Oracle. Các varchars NULL được coi là chuỗi rỗng.

select NULL || 'abc' from DUAL;

năng suất abc . DBMS khác sẽ trả về NULL trong những trường hợp này.

Khi bạn muốn thể hiện rõ ràng, rằng một giá trị được gán, bạn phải sử dụng cái gì đó như ''.

Và bạn phải lo lắng liệu việc cắt tỉa không có kết quả trống trong NULL

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

Nó làm.

Bây giờ nhìn vào DBMS trong đó '' không giống với NULL (ví dụ: SQL-Server)

Làm việc với '' thường dễ dàng hơn và trong hầu hết các trường hợp không có nhu cầu thực tế để phân biệt giữa cả hai. Một trong những trường hợp ngoại lệ tôi biết, là khi cột của bạn đại diện cho một số cài đặt và bạn không mặc định trống cho chúng. Khi bạn có thể phân biệt giữa '' và NULL, bạn có thể bày tỏ rằng cài đặt của bạn trống và tránh áp dụng mặc định đó.



17

Nó phụ thuộc vào tên miền bạn đang làm việc. NULLcó nghĩa là không có giá trị (nghĩa là không có giá trị ), trong khi chuỗi rỗng có nghĩa là có giá trị chuỗi có độ dài bằng không.

Ví dụ: giả sử bạn có một bảng để lưu trữ dữ liệu của một người và nó chứa một Gendercột. Bạn có thể lưu các giá trị là 'Nam' hoặc 'Nữ'. Nếu người dùng có thể chọn không cung cấp dữ liệu giới tính, bạn nên lưu dữ liệu đó dưới dạng NULL(tức là người dùng không cung cấp giá trị) và không phải chuỗi trống (vì không có giới tính có giá trị '').


7
Nếu người dùng chọn không cung cấp giới tính, chắc chắn bạn nên lưu trữ "Từ chối cung cấp". NULL là mơ hồ; điều đó cũng có nghĩa là "khách hàng chưa được hỏi", "khách hàng xác định giới tính không có trong danh sách của chúng tôi", v.v.
Jon of All Trades

8

Một điều đáng lưu ý là khi bạn có một trường không bắt buộc, nhưng bất kỳ giá trị nào hiện diện phải là duy nhất sẽ yêu cầu bạn lưu trữ các giá trị trống dưới dạng NULL. Mặt khác, bạn sẽ chỉ có thể có một bộ dữ liệu với giá trị trống trong trường đó.

Ngoài ra còn có một số khác biệt với đại số quan hệ và giá trị NULL: NULL! = NULL chẳng hạn.


4
Thực tế không phải là trường hợp mà NULL! = NULL, vì đó là NULL. ;-)
Peter Eisentraut

1
Lưu ý rằng MS SQL không tuân theo quy tắc này: nhiều giá trị NULL sẽ vi phạm một UNIQUEràng buộc. May mắn thay, bắt đầu từ năm 2008, bạn có thể sử dụng một chỉ mục được lọc để có hành vi phù hợp.
Jon của tất cả các giao dịch


4

Một suy nghĩ mới, ảnh hưởng lớn đến sự lựa chọn của bạn NULL/ NOT NULLlà nếu bạn đang sử dụng một khung. Tôi sử dụng symfony rất nhiều và sử dụng NULLcác trường cho phép đơn giản hóa một số mã và kiểm tra dữ liệu khi thao tác dữ liệu.

Nếu bạn không sử dụng khung hoặc nếu bạn đang sử dụng các câu lệnh sql đơn giản và xử lý, tôi sẽ chọn bất kỳ lựa chọn nào bạn cảm thấy đơn giản hơn để theo dõi. Tôi thường thích NULL để việc thực hiện các INSERTcâu lệnh không trở nên tẻ nhạt mà quên đặt các trường trống thành NULL.


câu hỏi là về NULL so với chuỗi rỗng (trong một cột nullable, IMO), không phải NULL vs KHÔNG NULL, phải không?
Gan

một phần của câu hỏi về lưu trữ khiến tôi nghĩ rằng anh ta có thể đang nghĩ về Null / Not Null
Patrick

hoặc @everyone khác liên quan đến hàm ý của NULL vs KHÔNG NULL, bạn có thể tham khảo điều này: dba.stackexchange.com/q/63/107
Gan

2

Phải làm việc với Oracle ( không cho phép bạn phân biệt ) Tôi đã đi đến kết luận sau:

  • Từ một POV logic, nó không thành vấn đề. Tôi thực sự không thể nghĩ ra một ví dụ hấp dẫn trong đó phân biệt giữa NULL và chuỗi không độ dài thêm bất kỳ giá trị nào trong DBMS.

  • Từ đó: Bạn có một NULLcột có thể không cho phép zero-len ''(giải pháp Oracle-ish) hoặc một NOT NULLcột cho phép zero-len.

  • Và từ kinh nghiệm của tôi, ''làm cho rất nhiều ý nghĩa hơn khi xử lý dữ liệu, như bình thường bạn muốn xử lý sự vắng mặt của một chuỗi như là chuỗi rỗng: Concatenation, So sánh vv

Lưu ý: Để quay lại trải nghiệm Oracle của tôi: Giả sử bạn muốn tạo truy vấn cho yêu cầu tìm kiếm. Nếu bạn sử dụng, ''bạn chỉ có thể tạo WHERE columnX = <searchvalue>và nó sẽ hoạt động cho các tìm kiếm bình đẳng. Nếu bạn sử dụng NULLbạn phải làm WHERE columnX=<searchvalue> or (columnX is NULL and serchvalue is NULL). Bah! :-)


2

Chúng cũng khác với quan điểm thiết kế:

ví dụ

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

CREATE UNIQUE INDEX t_AK1 ON t (name);

Giống như:

 \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)

Cho phép chèn một số dữ liệu:

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"

Bây giờ hãy thử với 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

Điều này được cho phép.

Soooooo: nulls không phải là chuỗi tầm thường cũng không phải ngược lại.

Chúc mừng


1

Nếu chúng ta nói về lý thuyết, thì các quy tắc của Codd nói rằng RDBMS phải xử lý NULLcác giá trị theo một cách đặc biệt.

Làm thế nào chính xác được sử dụng là tùy thuộc vào kiến ​​trúc sư cơ sở dữ liệu, tùy thuộc vào miền thực tế - nhiệm vụ - dự án - ứng dụng - khu vực.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.