В то время как другие ответы верны, что существуют лучшие подходы к вашему конкретному вопросу, можно создать таблицу из одной строки, добавив фиктивный столбец перечисления только с одним регистром и сделав его UNIQUE KEY
(илиPRIMARY KEY
) таблицы:
mysql> CREATE TABLE only_one_row (
restriction ENUM('') NOT NULL,
single_row_value DATETIME NOT NULL,
PRIMARY KEY (restriction)
);
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO only_one_row (single_row_value) VALUES (NOW());
Query OK, 1 rows affected (0.00 sec)
mysql> INSERT INTO only_one_row (single_row_value) VALUES ('2016-01-01');
ERROR 1062 (23000): Duplicate entry '' for key 'PRIMARY"
mysql> SELECT * FROM only_one_row;
+-------------+---------------------+
| restriction | single_row_value |
+-------------+---------------------+
| | 2016-01-01 00:00:00 |
+-------------+---------------------+
Это работает, потому что столбец может иметь только одно значение (ENUM
имеет только один регистр и не может быть NULL
), а *Клавиша 1008 * (или PRIMARY
) заставляет каждую строку в таблице иметь различное значение для столбца.
Это может быть расширено очевидным образом для создания таблиц, которые могут содержать только от 0 до любогоопределенное количество строк, вплоть до практических ограничений ENUM
.Предел в MySQL 5.7 фактически составляет 255 случаев, но к этому моменту было бы легче взять вместо UNQIUE KEY
столбец TINYINT UNSIGNED
.Однако я не смог найти способ обеспечить, чтобы в таблице было или 0 или N строк;это решение будет применять только «от 0 до N», так как MySQL не имеет рабочих ограничений CHECK
.(Конечно, где N - единица, как в этом примере, достигается тот же эффект.)
Примечание : хотя может показаться возможным использовать сгенерированный виртуальный столбец дляизбегайте использования дополнительного байта памяти для ограничительного перечисления, к сожалению, большинство версий MySQL и MariaDB будут выдавать различные ошибки, если вы попробуете это, либо потому, что постоянное значение не может использоваться для сгенерированного столбца, либо если вы обманываете базу данных вэто разрешено (например, с использованием GENERATED ALWAYS AS (LEAST(GREATEST(single_row_value,0),0)) VIRTUAL
), потому что механизмам хранения не нравится размещать индексы в виртуальных сгенерированных столбцах.Это задокументировано для работы с InnoDB в MySQL начиная с версии 5.7.8, но это точно не работает в MariaDB 10.1 на момент написания этой статьи.
Отредактировано, чтобы добавить: Это не надежно.Значение «error» для ENUM
равно нулю, а индексы начинаются с единицы, поэтому INSERT INTO only_one_row VALUES (0,...); INSERT INTO only_one_row VALUES (1,...);
будет успешным.Тем не менее, это условие вряд ли возникнет при нормальной работе, и все еще легче отслеживать, чем триггер!