Невидимі колонки (MySQL 8.0.23+) не потрапляють у SELECT * і не потребують значення в INSERT без списку колонок. Явно названі - працюють як звичайні.
ALTER TABLE orders ADD COLUMN internal_note TEXT INVISIBLE;
SELECT * FROM orders; -- internal_note немає
SELECT id, internal_note FROM orders; -- є
Навіщо: додати колонку до таблиці, не зламавши старий код, що робить SELECT * чи INSERT INTO t VALUES (...) без переліку колонок. Колонку можна поступово впровадити, а потім зробити видимою.
Згенерований невидимий первинний ключ (GIPK) (MySQL 8.0.30+). Якщо увімкнено sql_generate_invisible_primary_key, таблиця, створена без первинного ключа, автоматично отримує невидиму колонку:
my_row_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT INVISIBLE PRIMARY KEY
Чому таблиця без первинного ключа - проблема в MySQL:
- InnoDB однаково потрібен кластерний ключ. Без первинного ключа він бере перший унікальний
NOT NULLіндекс, а якщо такого немає - створює прихований 6-байтовий ідентифікатор. Але цей ідентифікатор спільний для всіх таких таблиць сервера, і його лічильник - точка конкуренції. - Реплікація на основі рядків: щоб застосувати
UPDATEчиDELETEна репліці, потрібно знайти рядок. Без ключа репліка шукає повним переглядом таблиці для кожного рядка - велике оновлення на primary перетворюється на години затримки реплікації. - Group Replication і InnoDB Cluster взагалі вимагають первинного ключа на кожній таблиці.
- Багато інструментів (онлайн-зміна схеми, деякі CDC-конектори) не працюють з таблицями без ключа.
GIPK вирішує це автоматично, не змінюючи видимої структури таблиці для застосунку.
Практичний висновок: кожна таблиця має мати первинний ключ, і краще явний ($table->id()). GIPK - страховка для таблиць, створених сторонніми інструментами чи без уваги. Проміжні таблиці «багато-до-багатьох» отримують складений первинний ключ з двох зовнішніх.
Докладніше в документації: Згенеровані невидимі первинні ключі