Як працювати з випадковими літерами верхнього та нижнього регістрів примірника в db під час запиту?

Який найкращий спосіб вирішити випадкові літери верхнього та нижнього регістру при запиті по рядку в базі даних?

Чи існує якийсь стандартний спосіб, чи слід мені дозволити вносити записи в базу даних лише у нижній регістр і конвертувати їх пізніше?

Зараз я маю цей запит у PHP:

    $get_category = "select category_name from categories where category_name = ".$some_var;

але не впевнений, що це найкращий спосіб, коли ви маєте справу з записами, які можуть бути верхньою або нижньою.

Я використовую MySQL.

Дякую, Олексій

3

7 Відповіді

MySQL чутливий до регістру або не залежить від колаборації. Виберіть зіставлення, яке закінчується символом '_ci' (для нечутливого для регістру), а запити у цьому стовпці використовуватимуть порівняння без врахування регістру.

Іншим рішенням буде використання функції UPPER для перетворення стовпця та значення пошукового запиту у верхній регістр, але при цьому будь-які індекси у стовпці не будуть використовуватися.

6
додано
привіт, не дуже добре знайомий з колаборацією. Це те, що є частиною запиту? Або структура таблиці? Як мені це зробити?
додано Автор GeekedOut, джерело
Це частина структури таблиці. Ви можете встановити зіставлення за базою даних, таблицею або стовпцем. Ви можете вибрати його в PHPMyAdmin або встановити його за допомогою оператора DDL. Ось інформація про те, що таке зіставлення. І тут, як налаштувати його .
додано Автор GolezTrol, джерело
@ ПСТ Дякую, ви дійсно можете . Хоча документація незрозуміла про вплив на продуктивність (більш точне використання індексів). Я можу уявити, що це усуває використання індексів, як і upper , але я не впевнений.
додано Автор GolezTrol, джерело
Чи можете ви навести приклад або посилання для отримання додаткової інформації про "вибір співставлення, яке закінчується з" _ci "? Моє Googlling не виявило, як це зробити.
додано Автор Marvo, джерело
COLLATION також може бути вказаний як LIKE. Не впевнений в інших випадках.
додано Автор user166390, джерело
@GolezTrol Хороша думка про можливі індекси взаємодії ...
додано Автор user166390, джерело

За замовчуванням зібрання MySQL нечутливі до регістру, тому "Hello" та "HeLLo" обидва рівні. Якщо вам потрібно примусити дані до послідовного кожуха, ви можете використовувати LOWER() і рядкові функції UPPER() .

1
додано

Що я зробив у минулому, коли мені потрібно було зберегти випадок оригінального рядка (наприклад, ім'я входу) - це створити інший стовпець із значенням, нормованим (у верхньому чи нижньому регістрі). Таким чином, я може виконувати ефективні порівняння, просто перетворивши рядок, який я порівнюю з тією ж самою справою.

Якщо продуктивність не є проблемою (як, наприклад, не велика кількість даних), то просто застосуйте верхній() або нижчий() до стовпчика, в якому пункт робить цей трюк. Але це гарантує сканування столу.

1
додано

Загальний шаблон полягає в рівненні ігрового поля, і зробити обидва рядки порівняння однаковим. Наприклад:

$get_category = "select category_name from categories 
    where lower(category_name) = ".strtolower($some_var);
1
додано

Ви також можете спробувати це:

"виберіть назву категорії з категорій, де LOWER (category_name) = LOWER (". $ some_var. ")";

але це може бути повільним (було б швидко, якщо ви зберігатимете нижченаведену категорію_назва в базі даних).

1
додано

SQL підтримує послідовності COLLATION, деякі з яких нечутливі до регістру. (Я не знаю, що в стандарті SQL говорить інакше, але проконсультуйтеся з документацією постачальника.)

У цьому випадку див. Розділ Чутливість справу в пошуку по рядках від керівництво MySQL. Ось список підтримуваних зіставлень , де < code> _ci -постифлексіровані зіставлення нечутливі до регістру.

Зауважте, що крім того, що вказано для схеми таблиці, COLLATION також може бути вказаний для оператора LIKE у запиті.

Щасливе кодування


Будь ласка, будь-ласка, будь-ласка, будь-ласка, використовуйте заповнювачі , щоб зберегти строки SQL і уникнути атак на введення SQL-ін'єкцій!

1
додано

Ви можете використовувати функцію UPPER sql для перевірки:

$get_category = "select category_name from categories where UPPER(category_name) = UPPER(".$some_var.");

Але це дійсно неефективно. Кращий спосіб полягає в тому, щоб зберігати значення як великий (або малий) від початку.

РЕДАГУВАТИ

Ви також повинні дійсно розглянути можливість використання параметризованих запитів замість простого об'єднання змінних в запит. Це допомагає запобігти ін'єкційним атакам SQL

For instance, you could prepare & execute your query like so:

 $preparedStatement = $db->prepare('SELECT category_name FROM categories WHERE UPPER(category_name) = :category');
 $preparedStatement->execute(array(':category' => strtoupper($some_var)));
 $rows = $preparedStatement->fetchAll();
0
додано