MySQL UNIQUE KEY и FOREIGN KEY один и тот же столбец не создается

У меня есть следующие таблицы /CREATE sintaxis:

CREATE TABLE `users` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `parentId` int(10) unsigned DEFAULT NULL,
  `fullName` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `alias` varchar(35) COLLATE utf8_unicode_ci DEFAULT NULL,
  `username` varchar(50) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  `password` varchar(255) COLLATE utf8_unicode_ci NOT NULL DEFAULT '',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_username` (`username`),
  UNIQUE KEY `uk_parentId_fullName_alias` (`parentId`,`fullName`,`alias`),
  KEY `fk_users_parentId` (`parentId`),
  CONSTRAINT `fk_users_parentId` FOREIGN KEY (`parentId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `userSettings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userId` int(11) unsigned NOT NULL,
  `settingsArray` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_userId` (`userId`),
  KEY `fk_userSettings_userId` (`userId`),
  CONSTRAINT `fk_userSettings_userId` FOREIGN KEY (`userId`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1

я пытаюсь создать одну таблицу с пользовательскими данными, а другую - с пользовательскими настройками. Когда я создаю таблицу userSettings, она не создает внешний ключ, что-то не так с синтаксисом создания? Это связано с созданием двух индексов для одного столбца?

Вот что я получаю после создания таблицы userSettings:

CREATE TABLE `userSettings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userId` int(11) unsigned NOT NULL,
  `settingsArray` text NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_userId` (`userId`),
  KEY `fk_userSettings_userId` (`userId`)
) ENGINE=MyISAM AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;

2 ответа

Как вы обнаружили, MyISAM не поддерживает внешние ключи. И то и другое users а также userSettings должен быть InnoDB.

[Мне] просто любопытно, является ли хорошей практикой использование UNIQUE_KEY и FOREIGN_KEY в одном столбце

Это означает, что userSettings таблица может иметь не более одной строки для каждого userId, Я думаю, вам нужен только один ряд на userId, потому что вы храните "массив" настроек, закодированных как-то в вашем settingsArray TEXT колонка. Это не очень хорошая практика.

Вы должны либо сохранить каждый параметр в своем собственном столбце:

CREATE TABLE `userSettings` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userId` int(11) unsigned NOT NULL,
  `isAdmin` bool NOT NULL,
  `timezone` varchar(10) NOT NULL,
  `theme` varchar(10) NOT NULL,
  ...other settings...
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_userId` (`userId`),
  KEY `fk_userSettings_userId` (`userId`)
) 

Или хранить несколько строк в userId, с одним именем настройки и значением в строке.

CREATE TABLE `userSettings` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `userId` int(11) unsigned NOT NULL,
  `setting` varchar(20) NOT NULL,
  `value` varchar(255) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_userId` (`userId`,`setting`),
  KEY `fk_userSettings_userId` (`userId`)
) 

Также удивительно, почему вам нужен id столбец для первичного ключа, если userId уже НЕ NULL и UNIQUE, и это, вероятно, ключ, который вы будете использовать для поиска строк в любом случае. Вы можете сделать userId ПЕРВИЧНЫЙ КЛЮЧ, а также (или userId, setting во втором примере) и пропустите id колонка.

Просто понял, что для пользователей таблицы ENGINE был InnoDB, а для таблицы userSettings ENGINE был MyISAM, изменил это и работал, мне просто любопытно, если использование UNIQUE_KEY и FOREIGN_KEY в одном столбце является хорошей практикой

Другие вопросы по тегам