Стандартное использование Z вместо NULL для представления отсутствующих данных?

Вне аргумента о том, следует ли когда-либо использовать NULL: я несу ответственность за существующую базу данных, которая использует NULL для обозначения отсутствующих или никогда не вводимых данных. Это отличается от пустой строки, что означает, что пользователь установил это значение и выбрал «пусто».

Другой исполнитель проекта твердо придерживается мнения, что NULL для меня не существуют; Я никогда не использую NULL, и никто другой не должен, по обе стороны аргумента. Однако меня смущает то, что, поскольку команда подрядчика ДЕЙСТВИТЕЛЬНО признает разницу между отсутствующим / никогда не введенным и намеренно пустым или указанным пользователем как неизвестным, они используют один символ `` Z '' во всем своем коде и хранимых процедурах для представления отсутствующих / никогда вводится с тем же значением, что и NULL во всей остальной базе данных.

Хотя наш общий клиент просил изменить это, и я поддержал этот запрос, команда считает это стандартной практикой среди администраторов баз данных, гораздо более продвинутых, чем я; они не хотят использовать NULL только на основании моего невежественного запроса. Итак, может ли кто-нибудь помочь мне преодолеть мое невежество? Есть ли какой-нибудь стандарт, небольшая группа людей или хотя бы один громкий голос среди экспертов по SQL, который выступает за использование буквы «Z» вместо NULL?

Обновлять

Мне нужно добавить ответ от подрядчика. Вот что он сказал, когда клиент попросил удалить специальные значения, чтобы разрешить NULL в столбцах без данных:

По сути, я спроектировал базу данных так, чтобы по возможности избегать значений NULL. Вот обоснование:

NULL в поле строки [VARCHAR] никогда не требуется, потому что пустая строка (нулевой длины) предоставляет точно такую ​​же информацию.

NULL в целочисленном поле (например, значение ID) можно обработать, используя значение, которое никогда не встречается в данных (например, -1 для целочисленного поля IDENTITY).

NULL в поле даты может легко вызвать сложности при вычислении даты. Например, в логике, которая вычисляет разницу в датах, такую ​​как разница в днях между [RecoveryDate] и [OnsetDate], логика взорвется, если одна или обе даты имеют значение NULL - если только для обеих дат не делается явный допуск. быть NULL. Это дополнительная работа и дополнительное управление. Если для [RecoveryDate] и [OnsetDate] используются даты по умолчанию или даты-заполнители (например, 01.01.1900), математические вычисления могут показывать необычные значения, но логика дат не нарушится.

Обработка NULL традиционно была областью, в которой разработчики допускали ошибки в хранимых процедурах.

За 15 лет работы администратором баз данных я решил, что лучше по возможности избегать значений NULL.

Похоже, это подтверждает в основном отрицательную реакцию на этот вопрос. Вместо применения общепринятого подхода 6NF к проектированию NULL, используются специальные значения, чтобы избежать NULL везде, где это возможно. Я опубликовал этот вопрос непредвзято, и я рад, что узнал больше о том, что NULL полезны / NULL - это злые дебаты, но теперь я вполне спокойно называю подход «особых значений» полной ерундой.

пустая строка (нулевой длины) предоставляет точно такую ​​же информацию.

Нет, это не так; в существующей базе данных, которую мы модифицируем, NULL означает, что никогда не вводился, а пустая строка означает, что введена как пустая.

Обработка NULL традиционно была областью, где разработчики допускали ошибки в хранимых процедурах.

Да, но эти ошибки были сделаны тысячи раз тысячами разработчиков, и уроки и предостережения, позволяющие избежать этих ошибок, известны и задокументированы. Как уже упоминалось здесь: принимаете ли вы значения NULL или отклоняете их, представление отсутствующих значений является решенной проблемой. Нет необходимости изобретать новое решение только потому, что разработчики продолжают делать легко устранимые (и легко идентифицируемые) ошибки.


В качестве сноски: я был администратором баз данных и разработчиком более 20 лет (что, безусловно, достаточно для меня, чтобы понять разницу между инженером базы данных и администратором базы данных). На протяжении всей моей карьеры я всегда был в лагере полезности нулевых значений, хотя я знал, что несколько очень умных людей не соглашались с этим. Я крайне скептически относился к подходу с особыми ценностями, но недостаточно хорошо разбирался в академиках «Как избежать нулевого и правильного пути», чтобы занять твердую позицию. Я всегда люблю узнавать что-то новое - и через 20 лет мне еще есть чему поучиться. Спасибо всем, кто сделал это обсуждение полезным.


person Boris Nikolaevich    schedule 09.07.2011    source источник
comment
NULL существует для включения тройной логики, которая необходима для сохранения ссылочной целостности при отсутствии полной информация - я бы назвал полную и полнейшую чушь любому провозглашенному специалисту по БД, который категорически против него!   -  person gordy    schedule 10.07.2011
comment
Никогда не слышал об этой практике.   -  person Calvin Allen    schedule 10.07.2011
comment
Предложил ли подрядчик суррогатный NULL и для числовых данных?   -  person Andriy M    schedule 10.07.2011
comment
@Andriy: Это легко решить, все эксперты хранят числа в символьных полях и приводят (с Z-проверками!) По мере необходимости. Подождите, я не на том сайте.   -  person mu is too short    schedule 10.07.2011
comment
@Gordy - спасибо за ссылки; @Everyone - спасибо за валидацию!   -  person Boris Nikolaevich    schedule 10.07.2011
comment
Давно не был на Daily WTF, думаю, просто помочился.   -  person MatBailie    schedule 10.07.2011
comment
Я опаздываю, но добавить меня в стан WTF?!. Я думаю, вам нужно передать этому подрядчику один из этих   -  person OMG Ponies    schedule 10.07.2011
comment
Может быть, он делал Verilog раньше и ошибочно приравнивает Z (все равно) к NULL?   -  person hyperslug    schedule 10.07.2011
comment
У вас возникнет проблема, когда они узнают, что буква «Z» является допустимым значением. И этот день наступит.   -  person Petruza    schedule 10.07.2011
comment
Я подозреваю, что однажды этот подрядчик пытался выполнить WHERE Column = NULL и был сбит с толку, почему он не получил никаких результатов.   -  person Mike Caron    schedule 10.07.2011
comment
@Gordy Date и Darwen против NULL, и даже если мы не согласны с ними, я думаю, будет справедливо сказать, что они компетентные эксперты по базам данных. Также (не относящийся к базе данных) Hoare talk Null Ссылки: Ошибка в миллиард долларов - важное мнение экспертов с тех пор, как Хоар изобрел изобрел NULL в ALGOL.   -  person Alex Jasmin    schedule 10.07.2011
comment
@Alexandre - Абсолютно верные моменты, хотя этот вопрос был в контексте производственной системы, которая уже использует NULL (хорошо это или плохо).   -  person Boris Nikolaevich    schedule 10.07.2011
comment
@Boris, если вы хотите прочитать что-то серьезное и обоснованное от людей, которые против NULL, могу я порекомендовать короткую статью Как обрабатывать недостающую информацию без использования NULL (ссылка на PDF-файл из Домашняя страница Третьего манифеста) - Кстати, я не думаю, что NULLs всегда плохо, но замена его на 'Z' почти определенно плохая идея. .   -  person stakx - no longer contributing    schedule 10.07.2011
comment
Фундаментальный вопрос: как хранить недостающие данные (или, я думаю, скорее, как не хранить их ... или что-то в этом роде ... язык здесь попадает в день). Независимо от того, предпочитаете ли вы хранить null в базе данных или перейти к таблицам 6NF и просто не добавлять записи для отсутствующих данных, не имеет значения; дело в том, что отсутствующие данные - это решенная проблема. Вы можете сделать то же самое, и у обоих есть свои последователи и недоброжелатели, но никто (и я готов сделать такое обобщение), кто знает, что они делают, не порекомендует универсальное магическое значение, которое оптовая замена null.   -  person Adam Robinson    schedule 11.07.2011
comment
Единственная причина, по которой я могу избежать использования null, заключается в том, что вы думаете, что можете забыть проверить его. Вы, по крайней мере, с такой же вероятностью забудете проверить Z. Итак, вы переходите к жесткой практике неудач, ранней неудачи. Если вы собираетесь облажаться, можете увидеть его в разработке, а не отображать Zs вместо адреса получателя платежа после его развертывания.   -  person Bill K    schedule 11.07.2011
comment
Нечестно отрицать вопрос только потому, что вы поняли, что я говорю о вас; Я действительно пытался понять, откуда появился этот «стандарт», поскольку в прошлом я не подписывался под теорией дизайна Never NULL и поэтому не исследовал все обходные пути и общепринятые практики, позволяющие избежать NULL.   -  person Boris Nikolaevich    schedule 11.07.2011
comment
Я привел эту аналогию, описывая этот пост члену семьи: переходить улицу может быть опасно; Это традиционно место, где пешеходы могут пострадать, если они не будут осторожны. За 15 лет работы пешеходом я стараюсь не переходить улицу, если это вообще возможно. Поэтому я всегда перескакиваю через улицу.   -  person Boris Nikolaevich    schedule 14.07.2011
comment
LOL :) На основе вашего обновления; Ваш подрядчик сильно переиграл законное беспокойство. До такой степени, что затем он значительно упростил свои смягчающие действия. Значения-заполнители кодируют информацию неявно, а не явно, требуют дополнительной документации, могут конфликтовать с допустимыми данными, могут вызывать скрытые сбои в логике, в любом случае требуют обработки кода. Обеспокоенность действительна, решение нестандартное, наивное и опасное, и есть промышленно Стандартные альтернативные подходы.   -  person MatBailie    schedule 14.07.2011
comment
@BorisNikolaevich: Не Поэтому я всегда вместо этого перехожу через улицу. но поэтому я всегда делаю Z-образный мост, чтобы вместо этого переходить улицу.   -  person ypercubeᵀᴹ    schedule 01.12.2011
comment
Что произойдет как пользователь, если Z - допустимая запись требования?   -  person xQbert    schedule 23.12.2011
comment
Итак, когда они выполняют левое и правое соединения, объединяют ли они значения Z в свои результаты, чтобы избежать NULLS в соединенных таблицах? Где заканчивается безумие?   -  person xQbert    schedule 23.12.2011


Ответы (8)


Увольняйте подрядчика.

Ладно, серьезно, это не стандартная практика. Это можно увидеть просто потому, что все СУБД, с которыми я когда-либо работал, реализуют NULL, логику для NULL, учитывают NULL во внешних ключах, имеют другое поведение для NULL в COUNT и т. Д. И т. Д.

На самом деле я бы сказал, что использование «Z» или любого другого заполнителя еще хуже. Вам по-прежнему требуется код для проверки "Z". Но вам также необходимо задокументировать, что «Z» не означает «Z», это означает что-то еще. И вы должны убедиться, что такая документация прочитана. И что тогда произойдет, если Z когда-нибудь станет действительной частью данных? (Например, поле для инициала?)

На базовом уровне, даже не обсуждая справедливость NULL и Z, я бы настаивал на том, чтобы подрядчик придерживался стандартных практик, существующих в вашей компании, а не его. Применение его стандартной практики в среде с альтернативной стандартной практикой вызовет путаницу, накладные расходы на обслуживание, недопонимание и, в конце концов, приведет к увеличению затрат и ошибок.


РЕДАКТИРОВАТЬ

Есть случаи, когда, на мой взгляд, допустимо использование альтернативы NULL. Но только тогда, когда это сокращает объем кода, а не создает особые случаи, требующие учета.

Я использовал это, например, для данных с привязкой к дате. Если данные действительны между датой начала и датой окончания, код можно упростить, не имея значений NULL. Вместо этого НУЛЕВАЯ дата начала может быть заменена на «01 января 1900 года», а НУЛЕВАЯ дата окончания может быть заменена на «31 декабря 2079 года».

Это все еще может изменить поведение по сравнению с ожидаемым, поэтому его следует использовать с осторожностью:

  • WHERE end-date IS NULL больше не предоставляют данные, которые все еще действительны
  • Вы только что создали свою собственную ошибку тысячелетия
  • и т.п.

Это эквивалентно реформированию абстракций, так что все свойства всегда могут иметь допустимые значения. Это заметно отличается от неявного кодирования конкретного значения в произвольно выбранные значения.

Тем не менее, уволите подрядчика.

person MatBailie    schedule 10.07.2011
comment
+1 от меня; место: я бы на самом деле утверждал, что использование «Z» или любого другого заполнителя еще хуже. Вам по-прежнему требуется код для проверки "Z". Но вам также необходимо задокументировать, что «Z» не означает «Z», это означает что-то еще. - person Mitch Wheat; 10.07.2011
comment
Нам нужно специальное значение - не NULL, поскольку NULL - зло, - для представления отсутствующих данных. Что-то, что отличается от всех других значений, может быть, даже от самого себя (поскольку две неизвестные не могут быть приравнены просто потому, что они неизвестны). Очевидно, что некоторые столбцы не имеют смысла с этим значением, поэтому его следует запретить. Чтобы упростить задачу, нам потребуются специальные операторы, например IS UNKNOWN или IS NOT UNKNOWN. - person Mike Caron; 10.07.2011
comment
Великолепное предложение, Майк, но я предлагаю использовать термин Z вместо НЕИЗВЕСТНО. Как есть, ... FROM FOO WHERE AGE IS Z. - person WW.; 10.07.2011
comment
Подрядчики часто получают полезные советы, основанные на глубоком опыте, но то, что такое иногда случается, не означает, что вы должны следовать за овцой через рекомендуемый опасный обрыв. Сообщите им, что вы являетесь хозяином и владельцем базы данных: разработка будет осуществляться в соответствии с указаниями: соблюдай или умри. - person wallyk; 10.07.2011
comment
Если пользователь вводит Z, то, очевидно, вы сохраняете ZZ. Если они входят в ZZ, вы сохраняете ZZZ и так далее. Это требует, чтобы вы увеличили все столбцы на один символ, но это не должно быть проблемой. - person Chas. Owens; 10.07.2011
comment
Кроме того, назовите и опозорите вашего подрядчика, чтобы мы могли быть уверены, что мы его тоже никогда не наймем. - person Tom O'Connor; 10.07.2011
comment
@Tom - я был бы готов сделать это для всех, кто свяжется со мной напрямую, но не на общедоступном сайте. Я уверен, что есть люди, которые так же относятся к моим навыкам заключения контрактов и разработки, и я бы предпочел, чтобы Карма не расплачивалась за публичное выступление разработчика, с которым я не согласен. Да, и с которым, по-видимому, не согласна большая часть сообщества StackOverflow. - person Boris Nikolaevich; 11.07.2011
comment
+1 от меня в целом - но особенно для редактирования, где может иметь смысл использовать значения столбов забора для диапазонов дат (минимальная дата / максимальная дата) из-за того, сколько кода он может сэкономить - особенно если вам нужно сравнивать / проверять на совпадение диапазонов дат. В этих случаях минимальная дата означает, что всегда, а максимальная дата означает до вечности, что отличается от NULL, что означает не уверен или не заботится. - person Joel Brown; 12.07.2011

Это одно из самых странных мнений, которые я когда-либо слышал. Использование магического значения для представления «нет данных», а не NULL, означает, что каждый фрагмент кода, который у вас есть, должен будет обрабатывать результаты, чтобы учесть / отбросить значения «без данных» / «Z».

NULL является особенным из-за того, как база данных обрабатывает его в запросах. Например, возьмите эти два простых запроса:

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

Если name когда-либо имеет значение NULL, очевидно, что он не будет отображаться в результатах первого запроса. Что еще более важно, это не будет отображаться и во вторых результатах запроса. NULL не соответствует ничему, кроме явного поиска NULL, как в:

select * from mytable where name is NULL;

А что произойдет, если в данных может быть допустимое значение Z? Допустим, вы храните чей-то средний инициал? Можно ли отнести Закари Зонкаса к тем людям, у которых нет инициалов в середине? Или ваш подрядчик придумал бы еще одно волшебное средство, чтобы справиться с этим?

Избегайте магических значений, которые требуют от вас реализации функций базы данных в коде, который база данных уже полностью способна обрабатывать. Это решенная и хорошо изученная проблема, и, возможно, ваш подрядчик никогда не понимал понятие NULL и поэтому избегает его использования.

person unpythonic    schedule 10.07.2011

Если домен допускает пропущенные значения, тогда использование NULL для представления «undefined» совершенно нормально (для чего он нужен). Единственным недостатком является то, что код, потребляющий данные, должен быть написан для проверки наличия NULL. Я всегда так поступал.

Я никогда не слышал (и не видел на практике) использования буквы «Z» для представления недостающих данных. Что касается «подрядчик называет это« стандартной практикой »среди администраторов баз данных», может ли он предоставить некоторые доказательства этого утверждения? Как упоминал @Dems, вам также необходимо задокументировать, что «Z» не означает «Z»: как насчет столбца MiddleInitial?

Как Аарон Альтон и многие другие, Я считаю, что значения NULL являются неотъемлемой частью дизайна базы данных и должны использоваться там, где это необходимо.

person Mitch Wheat    schedule 10.07.2011
comment
Я думаю, что ключ здесь в том, если домен допускает пропущенные значения ... Мне кажется, что есть время и место, чтобы поддержать использование NULL, а также время и место, чтобы их избегать, и требуется некоторая мудрость, чтобы знать различия. Иногда у меня возникает ощущение, что, когда младший DBE / DBA читает предупреждение, например, значения NULL могут вызывать неожиданные результаты в запросах и вычислениях, если вы не учитываете их поведение, его резкая реакция заключается в том, чтобы пометить все использование NULL как плохое. . Как только это становится религиозным мнением, оно остается с ним до конца его карьеры. - person Boris Nikolaevich; 10.07.2011
comment
Если вы забудете о предложении WHERE для DELETE или UPDATE, это может нанести вред вашей базе данных = ›никогда не используйте их. Либо получите данные правильно с первого раза, либо откройте таблицу в редакторе и сделайте это самостоятельно. - person MatBailie; 10.07.2011
comment
Также обратите внимание, что ВНЕШНИЕ соединения дают NULL и поэтому не должны использоваться. То же, СВЕРНУТЬСЯ. - person MatBailie; 10.07.2011
comment
Z используется для обозначения часового пояса GMT в некоторых стандартах. - person Erick Robertson; 10.07.2011
comment
@ Эрик, это еще одна причина не использовать Z, чтобы не обозначать никакой ценности. - person Boris Nikolaevich; 10.07.2011

Даже если вам каким-то образом удастся объяснить всем своим нынешним и будущим разработчикам и администраторам баз данных про "Z" вместо NULL, и даже если они все кодируют идеально, вы все равно запутаете оптимизатор, потому что он не будет знать, что вы это все придумали. .

Использование специального значения для представления NULL (которое уже является специальным значением для представления NULL) приведет к перекосу данных. например 1 января 1900 г. произошло так много всего, что это лишит оптимизатора возможности понять тот фактический диапазон дат, который действительно имеет отношение к вашему приложению.

Это похоже на решение менеджера: «Ношение галстука плохо сказывается на производительности, поэтому мы все будем носить малярный скотч на шее. Проблема решена».

person WW.    schedule 10.07.2011
comment
+1 только для фразы Использование специального значения для представления NULL (которое уже является специальным значением для представления NULL). . . - person Mike Sherrill 'Cat Recall'; 10.07.2011
comment
Я подумал, что галстук-бабочка был именно таким, галстук на шее, который был заменен на малярную ленту, считался более подходящим для этого случая ... - person Soren; 10.07.2011

Я никогда не слышал о широко распространенном использовании 'Z' вместо NULL.

(Между прочим, мне не особенно хотелось бы работать с подрядчиком, который прямо скажет вам, что они и другие «продвинутые» администраторы баз данных намного более осведомлены и лучше, чем вы.)

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

Как ваш подрядчик интерпретирует данные из последней строки?

Возможно, он выберет другое «магическое значение» в этой таблице, чтобы избежать столкновения с реальными данными 'Z'? Это означает, что вам нужно запомнить несколько магических значений, а также то, какое из них используется, где ... как это лучше, чем иметь только один магический токен NULL и помнить о трехзначных логических правилах (и подводных камнях), которые связаны с ним ? NULL по крайней мере стандартизирован, в отличие от 'Z' вашего подрядчика.

Мне тоже не очень нравится NULL, но бездумная замена его действительным значением (или, что еще хуже, несколькими действительными значениями) везде почти определенно хуже, чем NULL.

Позвольте мне повторить здесь мой вышеупомянутый комментарий для большей наглядности: если вы хотите прочитать что-то серьезное и обоснованное людьми, которые против NULL, я бы порекомендовал короткую статью " Как обрабатывать отсутствующую информацию без использования NULL " < / a> (ссылки на PDF-файл с домашней страницы Третьего манифеста).

person stakx - no longer contributing    schedule 10.07.2011

В принципе, ничто не требует наличия нулей для правильного проектирования базы данных. На самом деле существует множество баз данных, разработанных без использования null, и множество очень хороших дизайнеров баз данных и целые группы разработчиков, которые проектируют базы данных без использования null. В общем, хорошо проявлять осторожность при добавлении нулей в базу данных, потому что в дальнейшем они неизбежно приведут к неверным или неоднозначным результатам.

Я не слышал, чтобы Z назывался "стандартной практикой" в качестве значения-заполнителя вместо нулей, но я ожидаю, что ваш подрядчик имеет в виду концепцию контрольных значений в целом, которые иногда используются в базе данных дизайн. Однако гораздо более распространенный и гибкий способ избежать нулевых значений без использования «фиктивных» данных - это просто их спроектировать. Разбейте таблицу таким образом, чтобы каждый тип фактов записывался в таблицу, не имеющую «лишних», неопределенных атрибутов.

person nvogel    schedule 10.07.2011
comment
Я думаю, что подрядчик буквально означает использовать «Я», чтобы не знать. - person wallyk; 10.07.2011
comment
К сожалению, @wallyk в основном прав: это не академическое или теоретическое обсуждение; поскольку я сам разработчик, я изучил код и хранимые процедуры. Подрядчик использует буквальный символ «Z» для пропущенных / не введенных значений. (Значения, которые на самом деле неизвестны, но на которые дан ответ, никогда не равны NULL даже в текущем проекте базы данных; оба используют пустую строку для текстовых полей или символ 'U' для раскрывающихся списков, чтобы указать, что пользователь ответил на вопрос и ответ был я не знаю.) - person Boris Nikolaevich; 10.07.2011
comment
@dportas - я признаю, что правильный дизайн базы данных не требует использования нулей, но, поскольку я нахожусь в разделе Есть время и место для использования NULL, если вы знаете, как это сделать правильно, основная цель вопроса заключалась в чтобы понять, было ли использование буквы «Z» в хорошем дизайне базы данных кем-то из лагеря NoNULL стандартным, обычным или продвигаемым кем-либо. - person Boris Nikolaevich; 10.07.2011

В ответ на комментарии подрядчиков

  • Пустая строка ‹> NULL
  • Пустая строка требует хранения 2 байта + чтение смещения
  • NULL использует нулевое растровое изображение = быстрее
  • ИДЕНТИЧНОСТЬ не всегда начинается с 1 (зачем тратить половину диапазона?)

Вся концепция ошибочна, как и в большинстве других ответов здесь

person gbn    schedule 12.07.2011
comment
Несмотря на то что; Насколько я помню, в Oracle пустая строка имеет значение NULL. - person MatBailie; 18.07.2011

Хотя я никогда не видел «Z» как магическое значение для представления null, я видел, что «X» используется для обозначения поля, которое не было заполнено. Тем не менее, я видел это только в одном месте, и мой интерфейс чтобы это была не база данных, а XML-файл… поэтому я не был бы готов использовать это в качестве аргумента в качестве общепринятой практики.

Обратите внимание, что мы должны обрабатывать «X» специально, и, как упомянул Демс, мы должны задокументировать его, и людей это сбило с толку. В нашу защиту это навязывает нам внешний поставщик, а не то, что мы сами придумали!

person Paul Wagland    schedule 10.07.2011
comment
Это было бы очень запутанным для баз данных, в которых флажки хранятся, отмеченные полем символа 'X', а не отмеченные '' (пробел). Я надеюсь, что антивещество и материя не смешиваются в одной базе данных ... - person wallyk; 10.07.2011
comment
Я думаю, что это не получило голосов, потому что это не имеет прямого отношения к исходному вопросу о проектировании базы данных, но я, по крайней мере, должен сказать, что даже этот косвенный ответ только подчеркивает абсурдность подхода подрядчика. (Кроме того, я думаю, что с этого момента следует заменить No Votes на Z). - person Boris Nikolaevich; 23.07.2011
comment
Единственный ответ на вопрос. - person Pindatjuh; 04.08.2011