TINYTEXT как ПЕРВИЧНЫЙ ключ в MySQL? - PullRequest
0 голосов
/ 11 июля 2020

Записи в моей таблице однозначно идентифицируются по слову длиной от 5 до 10 символов, и я использую TINYTEXT (10) для столбца. Однако, когда я пытаюсь установить его как ПЕРВИЧНЫЙ ключ, я получаю сообщение об отсутствии size.

Исходя из моего ограниченного понимания документации, Size для ПЕРВИЧНЫХ ключей можно использовать для упрощения способа обнаруживать уникальное значение, т.е. когда первых нескольких символов (указанных Size) может быть достаточно, чтобы считать его уникальным совпадением. В моем случае size будет отличаться от 5 до 10 (все они latin1, поэтому они являются точными байтами на символ + 1 для длины). Два вопроса:

  1. Если я хотел использовать TINYTEXT в качестве ПЕРВИЧНОГО ключа, какой size я должен указать? Максимально доступное - 10 в данном случае? Или должен быть size строго ТОЧНЫЙ, например, если мой ключ - это слово длиной 6 символов, но я указываю Size для PK как 10 - он попытается прочитать все 10 и потерпит неудачу и вызвать мне исключение?
  2. Насколько плохо с точки зрения производительности будет использование [TINY] TEXT для PK? Все результаты Google приводят меня к мнениям и утверждениям «это ПЛОХО, вы уволены», но действительно ли это правда в данном случае, учитывая, что TINYTEXT составляет максимум 255, а я уже указал максимальную длину 10?

Ответы [ 3 ]

3 голосов
/ 11 июля 2020

для TINYTEXT нельзя указывать размер. Используйте VARCHAR (размер)

SQL Типы данных

2 голосов
/ 11 июля 2020
  1. MySQL / MariaDB может индексировать только первые символы текстовых полей, но не весь текст, если он слишком велик. Максимальный размер ключа составляет 3072 байта, и любое текстовое поле большего размера не может использоваться как KEY. Поэтому в текстовых полях длиннее 3072 байта вы должны явно указать, сколько символов будет индексироваться. При использовании VARCHAR или CHAR это можно сделать напрямую, потому что вы явно устанавливаете его при объявлении типа данных. Это не относится к * TEXT - у них нет такой опции. Решение состоит в том, чтобы создать первичный ключ следующим образом:

    CREATE TABLE mytbl (
        name TEXT NOT NULL,
        PRIMARY KEY idx_name(name(255))
    );
    

    Тот же трюк можно сделать, если вам нужно создать первичный ключ для поля VARCHAR, размер которого превышает 3072 байта, для полей BINARY и BLOB. В любом случае вы можете представить, что если два больших и разных текста начинаются с одних и тех же символов в первых 3072 байтах в начале, они будут рассматриваться системой как равные. Это может быть проблемой.

  2. Как правило, использование текстового поля в качестве первичного ключа - плохая идея. На то есть две причины:

    2.1. Это занимает намного больше времени обработки , чем использование целых чисел для поиска в таблице (WHERE, JOINS, et c). Ссылка старая, но актуальная;

    2.2. Любой внешний ключ в другой таблице должен иметь тот же тип данных, что и первичный ключ. Когда вы используете текст, это приведет к потере дискового пространства;

Примечание: разница между * TEXT и VARCHAR заключается в том, что содержимое полей * TEXT хранится не внутри таблицы, а снаружи. место в памяти. Обычно мы делаем это, когда нам нужно сохранить действительно большой текст.

0 голосов
/ 12 июля 2020

К вашему сведению, вы не можете указать размер для TINYTEXT в MySQL:

mysql> create table t1 ( t tinytext(10) );
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds 
to your MySQL server version for the right syntax to use near '(10) )' at line 1

Вы можете указать длину после TEXT, но это не работает так, как вы думаете оно делает. Это означает, что он выберет один из семейства типов ТЕКСТ, наименьший тип, который поддерживает не менее запрошенной вами длины. Но как только он это делает, он не ограничивает длину ввода. Он по-прежнему принимает любые данные до максимальной длины выбранного типа.

mysql> create table t1 ( t text(10) );
Query OK, 0 rows affected (0.02 sec)

mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `t` tinytext
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

mysql> insert into t1 set t = repeat('a', 255);
Query OK, 1 row affected (0.01 sec)

mysql> select length(t) from t1;
+-----------+
| length(t) |
+-----------+
|       255 |
+-----------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...