Books and articles about SQL Rambler's Top100 Сменить язык на: Русский 20 April 2024 00:49:23


www.sql-ex.ru
Skip Navigation Links  

 

Print  Версия для печати

На главную страницу

Худшие методы - чувствительные к регистру базы данных (или что-нибудь еще)

Andy Warren (оригинал: Worst Practices - Making Databases Case Sensitive (Or Anything Else))
Перевод Моисеенко С.И.

Мы уже рассмотрели некоторые интересные идеи и получили большое число откликов читателей. На этой неделе я хотел бы обсудить тему, предложенную читателем (и ведущим колонки!) Mindy Curnutt, - случая, когда вся база данных чувствительна к регистру. Может ли кто-нибудь утверждать, что чувствительность к регистру не добавляет уровень сложности? Написание хорошего программного обеспечения, вне зависимости от используемого вами языка, достаточно сложно и без этой проблемы!

Прежде, чем мы сможем всецело отнести чувствительность к регистру в реестр плохих методов, следует рассмотреть вопрос о том, зачем нам может понадобиться использовать это. Например, у нас есть приложение, которое является чувствительным к регистру, т.е. оно различает "FL" и "Fl" как коды для Флориды в справочной таблице. Поскольку нам требуется только один код для Флориды, как бы мы смогли обеспечить его? Созданием уникального индекса! Теперь мы можем иметь либо FL, либо Fl, но не оба. Даже при том, что приложение является чувствительным к регистру, нет никакой необходимости делать столбец (или таблицу, или базу данных) чувствительным к регистру. Так ли это?

Что, если .... мы уже имеем такие значения в таблице, которые не дают нам возможности создать уникальный индекс? (Чувствуете мою боль? Это - реальный пример!) Следует ли нам теперь оставить все как есть и обратить взгляд на использование чувствительных к регистру данных? Мне действительно не нравится такой выбор, поэтому давайте рассмотрим еще одну идею - использование триггеров на вставку и обновление (INSERT, UPDATE), которые позволят нам сделать чувствительную к регистру проверку таблицы и откатят любое изменение, которое нарушало бы наше "правило" не добавления каких-либо "дубликатов". Другими словами, не делайте проблему еще хуже, чем она есть.

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

Если Вы столкнулись с этой проблемой в SQL 7, то вам пришлось бы использовать метод триггеров или сделать всю базу данных чувствительной к регистру. То, какой способ предпочесть, будет вероятно зависеть от конкретного случая. Если бы Вы имели сто таблиц, которые потребовали бы этих триггеров, то было бы более разумным, менее трудоемким и более эффективным использовать чувствительность к регистру. Теперь, когда SQL 2000 позволяет для таблиц или даже для столбцов устанавливать чувствительность к регистру, мы можем применять намного более гибкие подходы.

Я знаю, что Вы думаете, - если это решает проблему, то почему бы это ни использовать?

На уровне столбца - не буду спорить. Мог бы, но не буду. Это достаточно хорошее решение. Возможно даже на уровне таблицы, если ваша ситуация требует этого. Но сделать всю базу данных чувствительной к регистру? Ни в коем случае! Это ведь не только данные, которые чувствительны к регистру, это - все, включая объекты. Пару статей назад я обсуждал вопрос о том, почему случай, когда не все объекты принадлежат dbo, только усложняет вашу жизнь (Вы могли иметь dbo.lookup, andy.lookup, и т.д). Сделайте вашу базу данных чувствительной к регистру, и Вы получите еще и следующее:

dbo.lookup
dbo.LOOKUP
dbo.LookUP
andy.lookup
andy.LOOKUP
andy.LookUP

И еще кое-что помимо этого. Как я говорил в начале, трудно ли написать хороший код, не примешивая сюда лишние проблемы? Одним из аргументов в пользу чувствительности среды к регистру является то, что это должно быть быстрее, поскольку центральный процессор не должен выполнять это за кадром:

Select * from table where state='fl'

Вероятно, на низком уровне выполнение будет примерно таким

select * from table where upper(state)=upper('fl')

Я уверен, что центральный процессор тратит на это один или два цикла, но имеет ли смысл экономить на таких незначительных издержках? Я могу представить, что как аппаратные средства, так SQL вполне прилично оптимизированы для выполнения этой операции. Даже если Вы решили сэкономить, стоит ли это дополнительной сложности кодирования? О какой сложности я говорю? Мне бы хотелось, чтобы в большинстве чувствительных к регистру сред окружения, Вы заканчивали бы так:

Select * from table where upper(state)='FL'

Почему? Потому что ваша справочная таблица имеет только один правильный код для Флориды! Теперь подумайте о том, как добиться этого, если, предположим, я ставлю Вам требование сделать коды штатов уникальными в справочной таблице независимо от регистра? Значит Вы должны отказаться от регистрозависимого столбца и сделать его НЕЧУВСТВИТЕЛЬНЫМ к регистру! Не можете использовать индекс? Мы вернулись к триггеру!

Знаете ли вы, что и Access, и VB считают данные чувствительными к регистру? Проверьте сами, выполнив следующий код:

Dim sItem1 As String
Dim sItem2 As String


sItem1 = "a"
sItem2 = "A"
If sItem1 = sItem2 Then
    MsgBox "Matched"
Else
     MsgBox "Didnt match"
End If

Если Вы измените сравнение на 'ucase$ (sItem1) =ucase$ (sItem2)', это будет всегда работать. Постойте-ка, Вы говорите, что код корректно работает в Access и без преобразования ucase$? Access 2000 (я полагаю, что и в Access 97 также) добавляет оператор "Option Compare Database" в каждый модуль. Закомментируйте его и посмотрите! VB также предлагает поддержку для выполнения регистронезависимого сравнения, посмотрите эту ссылку об использовании Option Compare Text

Интересная тема, ни так ли? Представьте, что вы используете язык, который является чувствительным к регистру - Java, Javascript, даже C#, я думаю. XML чувствителен к регистру!

Люди - не компьютеры. Мы не работаем хорошо с чувствительными к регистру данными или средами разработки. Позвольте компьютеру поднять эту тяжесть и скрыть сложность. Хорошо подумайте об имеющихся альтернативах прежде, чем Вы сделаете что-нибудь чувствительным к регистру.

Завершая, я понимаю, что не каждый согласится со мной. Так это или нет, я держу пари, что Вы имеете мнение относительно темы обсуждения. Как насчет того, чтобы поделиться этим мнением с нашими читателями - дать им возможность увидеть обе стороны вопроса? Ваши комментарии действительно станут прочитанными, и эта статья - результат одного из них!

07/08/2005

На главную страницу

Print  Версия для печати


Usage of any materials of this site is possible
only under condition of mandatory allocation of the direct link to a site
http://www.sqlbooks.ru
on each page where used materials are placed.

 Main   Articles    Books 
Рейтинг@Mail.ru Rambler's Top100 Alt Упражнения по SQL: обучение, тестирование, сертификация по языку SQL Copyright c 2002-2006. All rights reserved.