#php #mysql
#php #mysql
Вопрос:
У меня есть таблица под названием теги со столбцами id
, vid_id
, name
где id — это случайный идентификатор, сгенерированный с md5(uniqid());
помощью vid_id — это идентификатор видео, с которым связан тег, а name — это имя тега. Если видео содержит 5 тегов, все они сохраняются в таблице тегов. В последнее время я понял, что это плохой дизайн таблицы, потому что у меня много повторяющихся тегов. Я создал другую таблицу tag_map. В ней три столбца id
, vid_id
, tag_id
. Я хочу в основном реализовать решение «toxi», показанное здесь http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html .
Что я хочу сделать, так это каким-то образом перенести данные из тегов в tag_map, удалить столбец vid_id в тегах и удалить все дополнительные записи в тегах, чтобы каждая запись tag_map отображалась только на одну запись тега. Кто-нибудь знает эффективный способ сделать это? Я продолжаю думать:
$sql = 'SELECT * FROM tags';
$stmt3 = $conn->prepare($sql);
$result=$stmt3->execute();
while ($row = $stmt3->fetch(PDO::FETCH_ASSOC)) {
$id=md5(uniqid());
$sql = 'INSERT INTO tag_map VALUES (?,?,?)';
$insert = $conn->prepare($sql);
$result=$insert->execute(array($id,$row['vid_id'],$row['id']));
}
но потом я запутываюсь, когда пытаюсь придумать, как я собираюсь удалить лишние теги в тегах таблицы и сопоставить каждую запись tag_map только с одной записью tags. Любые советы будут с благодарностью.
Ответ №1:
Если я понимаю ваш пост, то вам нужна «таблица соединений» или «таблица соединений». (При повторном чтении, да, это решение «Toxi», на которое вы ссылаетесь. Не уверен, откуда он получил название «Toxi», но неважно.)
http://en.wikipedia.org/wiki/Junction_table
Вы хотите иметь таблицу, содержащую ровно одну строку для данного видео. И еще одна таблица, в которой ровно по одной строке для каждого тега. Тогда вам нужна третья промежуточная таблица, в которой по одной строке для каждой комбинации видео и тега. Таким образом, вы можете запросить третью таблицу соединений для всех видео, которые соответствуют данному тегу, или для всех тегов, которые соответствуют данному видео.
Я бы создал новую таблицу «tag» и таблицу «video_tag».
foreach ( video_record in the video table ) {
existingTags = read in list of tags for video_record from existing_tags_table
foreach ( tag in existingTags ) {
newTag = read tag from new tag table
if ( newTag == null ) {
save tag in new table
newTag.name = existing tag name
newTag.id = id from save procedure above
}
save entry in video_tag( video.id, newTag.id )
}
}
Затем удалите старую таблицу тегов. Если вы хотите, сделайте некоторое переименование новых таблиц тегов.
Комментарии:
1. У меня есть таблица соединений. Эта таблица называется tag_map, она объединяет теги таблицы и видео таблицы. Проблема в том, что у меня раньше не было таблицы соединений, поэтому у меня есть все эти записи в тегах. Мне нужно как-то организовать данные, которые у меня есть в тегах, и перераспределить их в tag_map, чтобы структура функционировала должным образом.
2. Большое спасибо, что нашли время, чтобы помочь мне, Марво!
3. Внес изменения, чтобы указать, что когда вы читаете в существующих тегах, вы читаете их для видеозаписи, которую вы только что прочитали. Надеюсь, эта ошибка вас не задержала. (Конечно, в вашей старой модели идентификатор видео был прямо там, в таблице тегов, так что вы, вероятно, поняли это.) Удачи!
Ответ №2:
Одна вещь, которую вы могли бы сделать, это установить vid_id
tag_id
пару и в качестве первичного ключа в вашей новой tag_map
таблице. Таким образом, когда вы выполняете алгоритм, который вы перечислили выше, повторяющиеся записи карты создаваться не будут, но у вас все равно будет по одному для каждого тега. Затем вы можете запустить запрос для удаления дубликатов в tags
таблице, подобной этой:
DELETE FROM TAGS WHERE ID NOT IN (SELECT tag_id FROM TAG_MAP)
Комментарии:
1. Спасибо за ввод, но это не сработает, чувак. vid_id и tag_id не являются уникальными в таблице tag_map. Для одного и того же видео может быть много записей, и tag_id можно использовать для сопоставления разных видео с одним и тем же тегом.
2. Я предполагаю, что я пытался сказать, что пара (vid_id, tag_id) должна быть первичным ключом вашей таблицы tag_map. Таким образом, у вас все равно может быть одно и то же сопоставление идентификатора тега с разными идентификаторами vid_id, но это не позволит вставлять повторяющиеся записи во время вашей нормализации. Я делаю что-то подобное в своем собственном проекте. Я, вероятно, что-то здесь упускаю 🙂