Câu hỏi Sử dụng tiêu chuẩn 'Z' thay vì NULL để biểu thị dữ liệu bị thiếu?


Ngoài lập luận về việc liệu có nên sử dụng NULL hay không: Tôi chịu trách nhiệm về một cơ sở dữ liệu hiện có sử dụng NULL để có nghĩa là dữ liệu "bị thiếu hoặc không bao giờ nhập". Nó khác với chuỗi rỗng, có nghĩa là "người dùng đặt giá trị này và họ đã chọn 'trống'."

Một nhà thầu khác trong dự án là vững chắc về "NULL không tồn tại đối với tôi, tôi không bao giờ sử dụng NULL và không ai khác nên, hoặc là" bên của đối số. Tuy nhiên, điều gây nhầm lẫn cho tôi là do nhóm của nhà thầu DOES thừa nhận sự khác biệt giữa "thiếu / không bao giờ nhập" và "cố ý trống hoặc được chỉ định bởi người dùng là không xác định", họ sử dụng một ký tự 'Z' trong suốt mã của họ và các thủ tục được lưu trữ đại diện cho "thiếu / không bao giờ nhập" với cùng ý nghĩa như NULL trong phần còn lại của cơ sở dữ liệu.

Mặc dù khách hàng dùng chung của chúng tôi đã yêu cầu điều này được thay đổi và tôi đã hỗ trợ yêu cầu này, nhóm đã trích dẫn điều này là "thực hành tiêu chuẩn" trong số các DBA cao hơn nhiều so với tôi; họ miễn cưỡng thay đổi để sử dụng NULL dựa trên yêu cầu không biết gì của tôi một mình. Vì vậy, bất cứ ai có thể giúp tôi vượt qua sự thiếu hiểu biết của tôi? Có bất kỳ nhóm tiêu chuẩn hay nhỏ nào của cá nhân hay thậm chí là một tiếng nói lớn trong số các chuyên gia SQL có chủ trương sử dụng 'Z' thay cho NULL không?

Cập nhật

Tôi có một phản ứng từ nhà thầu để thêm. Dưới đây là những gì anh ta nói khi khách hàng yêu cầu xóa các giá trị đặc biệt để cho phép NULL trong các cột không có dữ liệu:

Về cơ bản, tôi thiết kế cơ sở dữ liệu để tránh NULL bất cứ khi nào có thể. Đây là lý do:

Một NULL trong một chuỗi [VARCHAR] trường là không bao giờ cần thiết bởi vì một chuỗi rỗng (không chiều dài) cung cấp chính xác các thông tin tương tự.

NULL trong trường số nguyên (ví dụ: giá trị ID) có thể được xử lý bằng cách sử dụng giá trị sẽ không bao giờ xuất hiện trong dữ liệu (ví dụ: -1 cho trường số nguyên IDENTITY). 

Một NULL trong một trường ngày tháng có thể dễ dàng gây ra các biến chứng trong tính toán ngày tháng. Ví dụ, trong logic tính toán sự khác biệt ngày, chẳng hạn như sự khác biệt trong ngày giữa [RecoveryDate] và [OnsetDate], logic sẽ phát sinh nếu một hoặc cả hai ngày là NULL - trừ khi một khoản trợ cấp rõ ràng được thực hiện cho cả hai ngày NULL. Đó là công việc phụ và xử lý thêm. Nếu ngày "mặc định" hoặc "trình giữ chỗ" được sử dụng cho [RecoveryDate] và [OnsetDate] (ví dụ: "1/1/1900"), các phép tính toán học có thể hiển thị các giá trị "bất thường" - nhưng logic ngày sẽ không phát sinh.

Xử lý NULL theo truyền thống là một nơi mà các nhà phát triển mắc lỗi trong các thủ tục lưu sẵn. 

Trong 15 năm của tôi như là một DBA, tôi đã tìm thấy nó tốt nhất để tránh NULL bất cứ nơi nào có thể.

Điều này dường như xác nhận phản ứng chủ yếu tiêu cực đối với câu hỏi này. Thay vì áp dụng một phương pháp tiếp cận 6NF được chấp nhận để thiết kế ra NULL, các giá trị đặc biệt được sử dụng để "tránh NULL bất cứ khi nào có thể." Tôi đăng câu hỏi này với một tâm trí cởi mở, và tôi vui vì tôi đã học được nhiều hơn về "NULLs là hữu ích / NULLs là ác" tranh luận, nhưng bây giờ tôi khá thoải mái ghi nhãn cách tiếp cận 'giá trị đặc biệt' để hoàn thành vô nghĩa.

một chuỗi rỗng (không có độ dài) cung cấp chính xác cùng một thông tin.

Không, nó không; trong cơ sở dữ liệu hiện có mà chúng ta đang sửa đổi, NULL có nghĩa là "không bao giờ được nhập" và chuỗi rỗng có nghĩa là "được nhập là rỗng".

Xử lý NULL theo truyền thống là một nơi mà các nhà phát triển mắc lỗi trong các thủ tục lưu sẵn.

Có, nhưng những sai lầm đó đã được thực hiện hàng ngàn lần bởi hàng ngàn nhà phát triển, và những bài học và cẩn thận để tránh những sai lầm đó được biết và ghi lại. Như đã được đề cập ở đây: cho dù bạn chấp nhận hay từ chối NULL, biểu diễn của các giá trị bị thiếu là một Giải quyết vấn đề. Không cần phải phát minh ra một giải pháp mới chỉ vì các nhà phát triển tiếp tục thực hiện những sai lầm dễ dàng vượt qua (và dễ nhận biết).


Như một chú thích: Tôi đã là một DBE và nhà phát triển trong hơn 20 năm (chắc chắn là đủ thời gian để tôi biết sự khác biệt giữa một kỹ sư cơ sở dữ liệu và một quản trị viên cơ sở dữ liệu). Trong suốt sự nghiệp của tôi, tôi luôn ở trong trại "NULL là hữu ích", mặc dù tôi đã biết rằng một số người rất thông minh không đồng ý. Tôi đã rất hoài nghi về cách tiếp cận "các giá trị đặc biệt", nhưng không đủ thông thạo trong các học giả về "Làm thế nào để tránh NULL đúng cách" để làm cho một đứng vững chắc. Tôi luôn thích học những điều mới mẻ - và tôi vẫn còn rất nhiều thứ để học sau 20 năm. Nhờ tất cả những ai đã đóng góp để làm cho cuộc thảo luận này hữu ích.


76
2017-07-09 23:59


gốc


NULL tồn tại để kích hoạt logic lôgic đó là cần thiết để duy trì tính toàn vẹn tham chiếu trong trường hợp không có thông tin đầy đủ - Tôi sẽ gọi BS hoàn chỉnh và hoàn toàn trên bất kỳ chuyên gia DB được tuyên bố là người kiên quyết chống lại họ! - gordy
Chưa bao giờ nghe nói về thực hành này cả. - Calvin Allen
Nhà thầu có đề xuất một NULL thay thế cho dữ liệu số không? - Andriy M
@Andriy: Thật dễ dàng để giải quyết, tất cả các chuyên gia lưu trữ số trong các lĩnh vực nhân vật và đúc (với Z-kiểm tra!) Khi cần thiết. Oh chờ đã, Tôi đang ở sai trang. - mu is too short
Tôi nghi ngờ rằng tại một thời điểm, nhà thầu này đã cố gắng thực hiện WHERE Column = NULL và bối rối vì sao anh ta không nhận được kết quả nào. - Mike Caron


Các câu trả lời:


Sack nhà thầu của bạn.

Được rồi, nghiêm túc, đây không phải là thực hành tiêu chuẩn. Điều này có thể được nhìn thấy đơn giản bởi vì tất cả RDBMS mà tôi đã từng làm việc với thực hiện NULL, logic cho NULL, lấy tài khoản NULL trong khóa ngoài, có hành vi khác nhau cho NULL trong COUNT, v.v.

Tôi thực sự cho rằng việc sử dụng 'Z' hoặc bất kỳ người giữ chỗ nào khác đều tệ hơn. Bạn vẫn cần mã để kiểm tra 'Z'. Nhưng bạn cũng cần phải ghi rằng 'Z' không có nghĩa là 'Z', nó có nghĩa là cái gì khác. Và bạn phải đảm bảo rằng tài liệu đó được đọc. Và sau đó điều gì sẽ xảy ra nếu 'Z' trở thành một phần dữ liệu hợp lệ? (Chẳng hạn như một lĩnh vực cho một ban đầu?)

Ở cấp độ cơ bản, ngay cả khi không tranh luận về giá trị của NULL vs 'Z', tôi sẽ nhấn mạnh rằng nhà thầu tuân thủ các thực hành tiêu chuẩn tồn tại trong công ty của bạn, chứ không phải của mình. Việc thực hành tiêu chuẩn của mình trong một môi trường với một thực hành thay thế tiêu chuẩn sẽ gây nhầm lẫn, chi phí bảo trì, hiểu sai, và cuối cùng tăng chi phí và sai lầm.


CHỈNH SỬA

Có những trường hợp sử dụng một thay thế cho NULL là hợp lệ theo ý kiến ​​của tôi. Nhưng chỉ khi làm như vậy làm giảm mã, thay vì tạo ra các trường hợp đặc biệt đòi hỏi phải tính toán.

Ví dụ: tôi đã sử dụng dữ liệu đó cho dữ liệu ràng buộc ngày. Nếu dữ liệu hợp lệ giữa ngày bắt đầu và ngày kết thúc, mã có thể được đơn giản hóa bằng cách không có giá trị NULL. Thay vào đó, ngày bắt đầu NULL có thể được thay thế bằng '01 Jan 1900 'và ngày kết thúc NULL có thể được thay thế bằng '31 Dec 2079'.

Điều này vẫn có thể thay đổi hành vi từ những gì có thể được mong đợi, và vì vậy nên được sử dụng cẩn thận:

  • WHERE end-date IS NULL không còn cung cấp dữ liệu vẫn hợp lệ
  • Bạn vừa tạo lỗi thiên niên kỷ của riêng mình
  • v.v.

Điều này tương đương với cải cách trừu tượng sao cho tất cả các thuộc tính luôn có giá trị hợp lệ. Nó khác biệt rõ ràng với việc mã hóa hoàn toàn ý nghĩa cụ thể thành các giá trị được chọn tùy ý.

Tuy nhiên, sa thải nhà thầu.


104
2017-07-10 00:13



+1 từ tôi; tại chỗ trên: "Tôi thực sự sẽ cho rằng sử dụng 'Z' hoặc bất kỳ người giữ chỗ nào khác tệ hơn. Bạn vẫn cần mã để kiểm tra 'Z'. Nhưng bạn cũng cần phải ghi rằng 'Z' không có nghĩa là 'Z', nó có nghĩa là cái gì đó khác. " - Mitch Wheat
Những gì chúng ta cần là một giá trị đặc biệt - không phải NULL, vì NULL là ác - để biểu diễn dữ liệu bị thiếu. Cái gì đó khác với tất cả các giá trị khác, thậm chí có thể từ chính nó (vì, hai ẩn số không thể được đánh đồng đơn giản chỉ vì chúng chưa được biết). Một số cột rõ ràng sẽ không có ý nghĩa với giá trị này, và vì vậy nó nên bị cấm. Để dễ dàng, chúng tôi cần các toán tử đặc biệt như IS UNKNOWN hoặc IS NOT UNKNOWN. - Mike Caron
+1 - giá trị ma thuật tồi tệ hơn NULL. - APC
Các nhà thầu thường có lời khuyên tốt từ kinh nghiệm sâu sắc, nhưng chỉ vì điều đó đôi khi xảy ra, không có nghĩa là bạn phải đi theo con chiên trên vách đá nguy hiểm được đề nghị. Thông báo cho họ rằng bạn là chủ nhân và chủ sở hữu của cơ sở dữ liệu: phát triển sẽ được quy định như sau: tuân theo hoặc chết. - wallyk
Nếu người dùng nhập Z, thì rõ ràng là bạn lưu trữ ZZ. Nếu họ nhập ZZ, bạn lưu trữ ZZZ, v.v. Điều này đòi hỏi bạn phải làm cho tất cả các cột của bạn lớn hơn một ký tự, nhưng đó không phải là một vấn đề. - Chas. Owens


Đây là một trong những ý kiến ​​kỳ lạ nhất mà tôi từng nghe. Sử dụng giá trị phép thuật để biểu diễn "không có dữ liệu" thay vì NULL có nghĩa là mọi đoạn mã mà bạn có sẽ phải xử lý các kết quả vào tài khoản / loại bỏ các giá trị "không có dữ liệu" / "Z".

NULL là đặc biệt vì cách mà cơ sở dữ liệu xử lý nó trong các truy vấn. Ví dụ: lấy hai truy vấn đơn giản sau:

select * from mytable where name = 'bob';
select * from mytable where name != 'bob';

Nếu name là NULL, nó rõ ràng sẽ không hiển thị trong kết quả truy vấn đầu tiên. Quan trọng hơn, nó sẽ không hiển thị trong các kết quả truy vấn thứ hai. NULL không khớp với bất kỳ thứ gì khác ngoài tìm kiếm rõ ràng cho NULL, như sau:

select * from mytable where name is NULL;

Và điều gì sẽ xảy ra khi dữ liệu có thể có Z dưới dạng giá trị hợp lệ? Giả sử bạn đang lưu trữ chữ cái đầu của ai đó? Liệu Zachary Z Zonkas có được gộp lại với những người không có chữ viết tắt không? Hay nhà thầu của bạn sẽ đưa ra một giá trị ma thuật khác để xử lý việc này?

Tránh các giá trị ma thuật yêu cầu bạn phải thực hiện các tính năng cơ sở dữ liệu trong mã mà cơ sở dữ liệu đã hoàn toàn có khả năng xử lý. Đây là một vấn đề được giải quyết và được hiểu rõ, và nó có thể chỉ là nhà thầu của bạn không bao giờ thực sự làm ngơ khái niệm NULL và do đó tránh sử dụng nó.


26
2017-07-10 00:24





Nếu tên miền cho phép thiếu giá trị, sau đó sử dụng NULL để đại diện cho 'undefined' là hoàn toàn OK (đó là những gì nó có cho). Nhược điểm duy nhất là mã tiêu thụ dữ liệu phải được viết để kiểm tra NULL. Đây là cách tôi luôn làm.

Tôi chưa bao giờ nghe nói về (hoặc nhìn thấy trong thực tế) việc sử dụng 'Z' để đại diện cho dữ liệu bị thiếu. Khi "nhà thầu trích dẫn điều này là" thực hành tiêu chuẩn "giữa các DBAs", anh ta có thể cung cấp một số bằng chứng về xác nhận đó không? Như @Dems đã đề cập, bạn cũng cần ghi lại rằng 'Z' không có nghĩa là 'Z': MiddleInitial cột?

Như Aaron Alton và nhiều thứ khác, tôi tin rằng các giá trị NULL là một phần không thể thiếu trong thiết kế cơ sở dữ liệu, và nên được sử dụng khi thích hợp.


22
2017-07-10 00:05



+1: Liên kết đẹp :) [Tôi vẫn nói việc sa thải nhà thầu.] - MatBailie
Tôi nghĩ rằng chìa khóa ở đây là "Nếu tên miền cho phép thiếu giá trị ..." Có vẻ như với tôi rằng có một thời gian và một nơi để tán thành việc sử dụng NULL, và một thời gian và nơi để tránh chúng, và phải mất một số trí tuệ để biết sự khác biệt. Đôi khi tôi có cảm giác rằng khi một DBE DBA / DBA đọc báo trước, "giá trị NULL có thể gây ra kết quả không mong muốn trong các truy vấn và tính toán nếu bạn không tính đến hành vi của họ". xấu. Một khi nó trở thành một ý kiến ​​tôn giáo, nó gắn bó với anh ta cho phần còn lại của sự nghiệp của mình. - Boris Nikolaevich
Quên mệnh đề WHERE trên DELETE hoặc UPDATE có thể gây hại cho cơ sở dữ liệu của bạn => không bao giờ sử dụng chúng. Hoặc là lấy dữ liệu ngay lần đầu tiên hoặc mở bảng trong trình chỉnh sửa và tự làm. - MatBailie
Z được sử dụng để thể hiện múi giờ GMT theo một số tiêu chuẩn. - Erick Robertson
@ Erick, đó là một trong nhiều lý do không sử dụng Z để có nghĩa là "không có giá trị." - Boris Nikolaevich


Thậm chí nếu bạn bằng cách nào đó giải thích cho tất cả các nhà phát triển và DBA hiện tại và tương lai của bạn về "Z" thay vì NULL, và ngay cả khi họ mã hóa mọi thứ một cách hoàn hảo, bạn sẽ vẫn nhầm lẫn với trình tối ưu hóa vì nó sẽ không biết bạn đã nấu món này .

Sử dụng một giá trị đặc biệt để biểu diễn NULL (mà đã là một giá trị đặc biệt để biểu diễn NULL) sẽ dẫn đến độ lệch trong dữ liệu. ví dụ. Có rất nhiều điều xảy ra vào ngày 1 tháng 1 năm 1900 là nó sẽ loại bỏ khả năng của trình tối ưu hóa để hiểu rằng phạm vi ngày thực sự có liên quan đến ứng dụng của bạn.

Điều này giống như một người quản lý quyết định: "Mặc một chiếc cà vạt là xấu cho năng suất, vì vậy tất cả chúng ta sẽ đeo băng che quanh cổ của chúng tôi. Vấn đề được giải quyết."


17
2017-07-10 01:46



1 chỉ cho cụm từ "Sử dụng một giá trị đặc biệt để đại diện cho NULL (mà đã là một giá trị đặc biệt để đại diện cho NULL)". . . - Mike Sherrill 'Cat Recall'
Tôi nghĩ rằng một chiếc nơ-nơ chính xác như vậy, một chiếc cà vạt cổ được thay thế bằng băng dính được coi là phù hợp hơn cho dịp này ... - Soren


Tôi chưa bao giờ nghe nói về việc sử dụng rộng rãi 'Z' như là một thay thế cho NULL.

(Ngẫu nhiên, tôi không muốn làm việc với một nhà thầu nói với bạn rằng họ và các DBA "cao cấp" khác hiểu biết nhiều hơn và tốt hơn bạn.)

 +=================================+
 |  FavoriteLetters                |
 +=================================+
 |  Person      |  FavoriteLetter  |
 +--------------+------------------+
 |  'Anna'      |  'A'             |
 |  'Bob'       |  'B'             |
 |  'Claire'    |  'C'             |
 |  'Zaphod'    |  'Z'             |
 +---------------------------------+

Nhà thầu của bạn sẽ giải thích dữ liệu từ hàng cuối cùng như thế nào?

Có lẽ anh ta sẽ chọn một "giá trị ma thuật" khác trong bảng này để tránh va chạm với dữ liệu thực 'Z'? Có nghĩa là bạn phải nhớ nhiều giá trị ma thuật và cái nào cũng được sử dụng ở đâu ... thế nào là tốt hơn việc chỉ có một mã thông báo ma thuật NULLvà phải nhớ các quy tắc logic có giá trị ba (và những cạm bẫy) đi cùng với nó? NULL ít nhất là tiêu chuẩn hóa, không giống như nhà thầu của bạn 'Z'.

Tôi không đặc biệt thích NULL hoặc là, nhưng đừng thay thế nó bằng một giá trị thực tế (hoặc tệ hơn, với một vài giá trị thực tế) mọi nơi gần như chắc chắn tồi tệ hơn NULL.

Hãy để tôi lặp lại bình luận ở trên của tôi ở đây để hiển thị tốt hơn: Nếu bạn muốn đọc một cái gì đó nghiêm trọng và được căn cứ bởi những người chống lại NULL, Tôi sẽ giới thiệu bài viết ngắn "Cách xử lý thông tin còn thiếu mà không sử dụng NULL" (liên kết tới một tệp PDF từ Trang chủ Tuyên ngôn thứ ba).


9
2017-07-10 09:16





Không có gì về nguyên tắc yêu cầu null để thiết kế cơ sở dữ liệu chính xác. Trong thực tế có rất nhiều cơ sở dữ liệu được thiết kế mà không sử dụng null và có rất nhiều nhà thiết kế cơ sở dữ liệu rất tốt và toàn bộ các nhóm phát triển thiết kế cơ sở dữ liệu mà không sử dụng null. Nói chung nó là một điều tốt để thận trọng về việc thêm null vào một cơ sở dữ liệu bởi vì họ chắc chắn dẫn đến kết quả không chính xác hoặc mơ hồ sau này.

Tôi đã không nghe nói về việc sử dụng Z được gọi là "thực hành tiêu chuẩn" như là một giá trị giữ chỗ thay vì null nhưng tôi hy vọng nhà thầu của bạn đề cập đến khái niệm giá trị sentinel nói chung, đôi khi được sử dụng trong thiết kế cơ sở dữ liệu. Tuy nhiên, một cách phổ biến hơn và linh hoạt hơn để tránh null mà không sử dụng dữ liệu "giả" chỉ đơn giản là để thiết kế chúng ra. Phân chia bảng sao cho mỗi loại thực tế được ghi lại trong bảng không có thuộc tính "phụ", không xác định.


4
2017-07-10 07:24



Tôi nghĩ rằng các nhà thầu theo nghĩa đen có nghĩa là sử dụng 'Z' cho "không biết". - wallyk
Thật không may, @ wallyk về cơ bản là chính xác: đây không phải là một cuộc thảo luận về mặt lý thuyết hoặc học thuật; kể từ khi tôi là một nhà phát triển bản thân mình, tôi đã được thông qua mã và các thủ tục được lưu trữ. Nhà thầu đang sử dụng ký tự chữ 'Z' cho các giá trị bị thiếu / không được nhập. (Giá trị thực tế là "chưa biết nhưng được trả lời" không bao giờ là NULL ngay cả trong thiết kế cơ sở dữ liệu hiện tại; cả hai đều sử dụng chuỗi rỗng cho trường văn bản hoặc ký tự 'U' cho danh sách thả xuống để cho biết người dùng đã trả lời câu hỏi và câu trả lời là "Tôi không biết.") - Boris Nikolaevich
@ dportas - Tôi nhận ra rằng thiết kế cơ sở dữ liệu chính xác không yêu cầu sử dụng null, nhưng kể từ khi tôi đang ở trong "Có một thời gian và một nơi để sử dụng NULL nếu bạn biết làm thế nào để làm như vậy một cách chính xác," mục đích chính của câu hỏi là để hiểu liệu việc sử dụng 'Z' trong thiết kế cơ sở dữ liệu tốt hay không bởi ai đó của trại "NoNULL" là tiêu chuẩn, phổ biến hoặc được quảng cáo bởi bất kỳ ai. - Boris Nikolaevich


Trả lời ý kiến ​​của nhà thầu

  • Chuỗi rỗng <> NULL
  • Chuỗi rỗng yêu cầu bộ nhớ 2 byte + đọc bù
  • NULL sử dụng bitmap rỗng = nhanh hơn
  • IDENTITY không phải lúc nào cũng bắt đầu ở mức 1 (tại sao lại lãng phí một nửa phạm vi của bạn?)

Toàn bộ khái niệm là thiếu sót theo hầu hết các câu trả lời khác ở đây


3
2017-07-12 09:09



Mặc dầu; Theo như tôi nhớ lại, một chuỗi rỗng Là NULL trong Oracle. - MatBailie


Trong khi tôi chưa bao giờ thấy 'Z' như một giá trị ma thuật đại diện cho null, tôi đã thấy 'X' được sử dụng để đại diện cho một trường chưa được điền. Điều đó nói rằng, tôi chỉ thấy điều này ở một nơi và giao diện của tôi với nó không phải là một cơ sở dữ liệu, mà là một tệp XML ... vì vậy tôi sẽ không được chuẩn bị để sử dụng lý lẽ này cho việc thực hành phổ biến.

Lưu ý rằng chúng ta phải xử lý 'X' đặc biệt, và, như Dems đã đề cập, chúng ta phải ghi lại nó, và mọi người đã bị nhầm lẫn bởi nó. Trong phòng thủ của chúng tôi, điều này bị ép buộc bởi chúng tôi bởi một nhà cung cấp bên ngoài, không phải thứ gì đó mà chúng tôi tự nấu chín!


1
2017-07-10 01:10



Điều đó sẽ rất khó hiểu đối với các cơ sở dữ liệu lưu trữ các lựa chọn hộp kiểm được kiểm tra với một trường char của 'X', không được chọn '' (dấu cách). Tôi hy vọng phản vật chất và vật chất không được trộn lẫn vào cùng một cơ sở dữ liệu .... - wallyk
Tôi nghĩ rằng điều này không nhận được bất kỳ phiếu bầu nào vì nó không liên quan trực tiếp đến câu hỏi Thiết kế cơ sở dữ liệu ban đầu, nhưng ít nhất tôi phải nói rằng ngay cả phản ứng "tiếp tuyến" này chỉ nhằm nhấn mạnh sự phi lý của cách tiếp cận của nhà thầu. (Ngoài ra, tôi nghĩ rằng "No Votes" nên được thay thế bằng "Z" từ đây trở đi.) - Boris Nikolaevich
Câu trả lời duy nhất cho câu hỏi. - Pindatjuh