Найгірші методи (MS SQL Server) – чутливі до регістру бази даних (або що-небудь ще), Інші СУБД, Бази даних, статті

Ми вже розглянули деякі цікаві ідеї і отримали велике число відгуків читачів. На цьому тижні я хотів би обговорити тему, запропоновану читачем (і провідним колонки!) 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 чутливий до регістру!


Люди – не комп’ютери. Ми не працюємо добре з чутливими до регістру даними або середовищами розробки. Дозвольте комп’ютера підняти цей тягар і приховати складність. Добре подумайте про наявні альтернативи перш, ніж Ви зробите щось чутливим до регістру.


Завершуючи, я розумію, що не кожен погодиться зі мною. Так це чи ні, я тримаю парі, що Ви маєте думку щодо теми обговорення. Як щодо того, щоб поділитися цією думкою з нашими читачами – Дати їм можливість побачити обидві сторони питання? Ваші коментарі дійсно стануть прочитаними, і ця стаття – результат одного з них!

Andy Warren (Оригінал: Worst Practices – Making Databases Case Sensitive (Or Anything Else))
Переклад: Моісеєнко С.І.
Оригінал перекладу


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*