4 điểm bởi GN⁺ 2025-01-11 | 2 bình luận | Chia sẻ qua WhatsApp
  • Trong SQL, giá trị NULL được xử lý theo cách rất đặc biệt. Một cột có ràng buộc UNIQUE vẫn có thể chứa nhiều giá trị NULL.

    • Điều này là vì mỗi giá trị NULL được xem như một giá trị độc lập, khác với các giá trị NULL khác
    • SQLite, Postgres và MySQL đều hoạt động giống nhau.
  • Thiết lập tiêu chuẩn

    select '' = '';    -- Returns 1 (true) chuỗi rỗng thì bằng nhau   
    select 1 = 1;      -- Returns 1 (true) số thì bằng nhau   
    select 1 = 0;      -- Returns 0 (false) số khác nhau   
    select null = null; -- Returns NULL (null) hả?  
    
    • NULL là chỗ giữ chỗ cho một "giá trị chưa biết", nên hai giá trị chưa biết không được coi là bằng nhau
    • Dùng toán tử IS thì có thể kiểm tra định danh của NULL. Ví dụ, null is null trả về TRUE.
  • Về tính duy nhất

    • Khi một cột có ràng buộc UNIQUE chứa giá trị NULL, các giá trị NULL được coi là khác nhau nên không vi phạm ràng buộc duy nhất.
    • Ví dụ, ('ray@mail.com', NULL)('ray@mail.com', NULL) được coi là hai hàng khác nhau.
  • Vì sao NULL lại được xử lý như vậy

    • SQLite và các cơ sở dữ liệu tương thích SQL khác được triển khai theo cách này để xử lý NULL nhất quán với các cơ sở dữ liệu khác. Tài liệu chuẩn SQL gợi ý rằng NULL phải là duy nhất ở mọi nơi, nhưng trên thực tế đa số SQL engine không xử lý NULL là duy nhất trong SELECT DISTINCT hoặc UNION.
  • Cách đảm bảo tính duy nhất

    • Dùng cột sinh ra

      • Có thể giảm bớt vấn đề bằng cách tạo một cột luôn có giá trị xác định và không phải NULL. Ví dụ, có thể dùng COALESCE(deleted_at, '1970-01-01') để thay thế giá trị NULL.
      • Cách này có thể chiếm thêm không gian vì thêm trường vào bảng.
    • Dùng chỉ mục một phần

      • Có thể đảm bảo tính duy nhất bằng cách tạo chỉ mục một phần cho email chỉ khi deleted_at là NULL.
      • Chỉ mục một phần không làm bảng rộng hơn, tốn ít không gian hơn, và không gây lỗi khi lặp lại thao tác xóa cùng một cặp bản ghi.
  • Cập nhật

    • Oracle xử lý chuỗi rỗng như NULL.
  • Kết luận

    • Khi dùng ORM thì khó nhìn thấy, nhưng cách SQL xử lý NULL một cách đặc biệt có thể gây nhầm lẫn. Tài liệu chuẩn SQL không được cung cấp công khai và chỉ có thể lấy khi trả phí.

2 bình luận

 
iolothebard 2025-01-14

Mọi null đều kỳ quặc.
Vì thế, null bình thường của SQL lại trông như thể mới là thứ kỳ quặc…
Ở xứ sở người chột, kẻ hai mắt lại là bất thường…

 
GN⁺ 2025-01-11
Ý kiến trên Hacker News
  • NULL trong SQL dựa trên logic TRUE-FALSE-UNKNOWN của Kleene. Nếu đọc NULL là UNKNOWN thì nhiều phép toán sẽ dễ hiểu hơn một cách trực quan

    • TRUE OR UNKNOWN = TRUE, TRUE AND UNKNOWN = UNKNOWN, UNKNOWN XOR UNKNOWN = UNKNOWN, v.v.
    • NULL là một chỗ giữ chỗ biểu thị UNKNOWN, và không thể nói hai NULL là bằng nhau
    • Từ PostgreSQL 15, có thể tạo chỉ mục duy nhất bằng NULLS NOT DISTINCT
  • Khi khái niệm NULL được đưa vào trong thập niên 1970, đã có người nghĩ rằng nó sẽ gây ra rất nhiều nhầm lẫn trong tương lai. Giờ đã 45 năm trôi qua mà nó vẫn còn đang được bàn cãi

  • Cách hiểu trực quan về NULL: giá trị NULL trong một ô cụ thể của bảng là cách để biểu thị “không có giá trị”. Khi muốn các giá trị là duy nhất, các trường hợp không có giá trị thì không nên được tính đến

  • Hoài nghi về việc dùng ORM: ORM thì tiện, nhưng đã tạo ra một thế hệ không học được cách cơ sở dữ liệu quan hệ thực sự hoạt động. Cách vận hành của SQL NULL phù hợp với đại số quan hệ cơ bản, còn kiểu NULL theo phong cách C mới là vấn đề

  • Gợi nhớ đến sự hài hước của việc so sánh NULL trong đoạn hội thoại của một tập phim Blackadder

  • Thấy lạ khi trong Oracle, NULL lại được coi là giống với chuỗi rỗng

  • Trong ngữ cảnh hướng đối tượng, "null" hữu ích để biểu thị một thuộc tính cụ thể không có giá trị. Trong JavaScript có nullundefined; có thể xem undefined là không biết giá trị, còn null là không có giá trị

  • NULL không hề kỳ lạ theo nghĩa không có trùng lặp. Vì các NULL không bằng nhau nên chúng không thể bị coi là trùng. Nếu không thích ngữ nghĩa của NULL, có thể dùng giá trị sentinel

  • SQL NULL không hề kỳ lạ nếu xét đến cách bạn muốn logic quan hệ hoạt động thế nào trong các bản ghi có chứa giá trị không tồn tại