MySQL UNIQUE KEY и FOREIGN KEY один и тот же столбец не создается - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть следующие таблицы / 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 ]

0 голосов
/ 16 ноября 2018

Как вы обнаружили, 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 уже НЕ НЕДЕЙСТВИТЕЛЕН и УНИКАЛЬЕН, и это, вероятно, ключв любом случае вы будете искать строки.Вы можете также сделать userId ПЕРВИЧНЫЙ КЛЮЧ (или userId, setting во втором примере) и опустить столбец id.

0 голосов
/ 15 ноября 2018

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

...