Как сделать уникальные пары полей? - MySQL

Узнай цену своей работы

Формулировка задачи:

Проектирую БД, встал перед новой для меня задачей, мне необходимо иметь уникальные пары полей. Пусть будет БД с структурой id,uid,msg_id id - auto increment, uid соответственно id пользователя, а msg_id - номер сообщения этого пользователя. Я вполне понимаю что достаточно и двух полей, но мне необходимо иметь возможность вывести номер конкретного сообщения пользователя при необходимости, а значит каждое сообщение должно иметь свой УНИКАЛЬНЫЙ последовательный номер. И при удалении сообщения (а точнее присвоении в таблице ему статуса del), следующее сообщение должно иметь уже следующий номер. Как сделать так, что бы в записи с одинаковым uid не могло быть более одного одинакового msg_id? Unique, на сколько я понимаю, не позволяет иметь одинаковых записей в определенном поле вообще. То есть даже записи с разным uid, но одинаковым msg_id (например 1), не смогут существовать. Нужно мне это потому что при создании записи, я буду записывать в msg_id результат запроса
(SELECT `msg_id` FROM `table` WHERE `uid`=$uid)+1
И считаю что при определенных условиях возможна запись 2х(а может и более) сообщений с одинаковым msg_id, что в моей ситуации совершенно недопустимо. Если вы считаете что я как-то неправильно инкримерирую +1 в поле msg_id, можете сказать об этом. Если в вашем решении будет невозможно создать более одной записи с одним и тем же msg_id - это будет ответом на мой вопрос. p.s. Сейчас подумал о том что бы при создании записи увеличивать msg_id иначе, как-нибудь вроде "++", но на сколько я понимаю это не сработает.

Решение задачи: «Как сделать уникальные пары полей?»

textual
Листинг программы
mysql> create table tst_isam (
    ->   uid int not null,
    ->   msg_id int auto_increment,
    ->   primary key (uid, msg_id)
    -> ) engine = myisam default character set = cp1251;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into tst_isam(uid) values 
    -> (1), (1), (1), (3), (4), (1), (2), (3), (2), (1), (2), (3), (1), (2), (3);
Query OK, 15 rows affected (0.00 sec)
Records: 15  Duplicates: 0  Warnings: 0

mysql> -- ранее только одно значение для uid = 4 и будет добавлено (msg_id = 6)
mysql> insert into tst_isam values (4, 6);
Query OK, 1 row affected (0.00 sec)

mysql> -- но теперь новое значение будет увеличено от последнего добавленного т.е. msg_id будет равно 7
mysql> insert into tst_isam(uid) values (4);
Query OK, 1 row affected (0.00 sec)

mysql> select * from tst_isam order by uid, msg_id;
+-----+--------+
| uid | msg_id |
+-----+--------+
|   1 |      1 |
|   1 |      2 |
|   1 |      3 |
|   1 |      4 |
|   1 |      5 |
|   1 |      6 |
|   2 |      1 |
|   2 |      2 |
|   2 |      3 |
|   2 |      4 |
|   3 |      1 |
|   3 |      2 |
|   3 |      3 |
|   3 |      4 |
|   4 |      1 |
|   4 |      6 |
|   4 |      7 |
+-----+--------+
17 rows in set (0.00 sec)

mysql> -- и попробуем добавить уже существующую запись (id = 4, msg_id = 7)
mysql> insert into tst_isam values (4, 7);
ERROR 1062 (23000): Duplicate entry '4-7' for key 'PRIMARY'
mysql> -- так для innodb не работает :(
mysql> create table tst_innodb (
    ->   uid int not null,
    ->   msg_id int auto_increment,
    ->   primary key (uid, msg_id)
    -> ) engine = iy (msg_id, uid)
    -> ) engine = innodb default character set = cp1251;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'msg_id, uid)
) engine = innodb default character set = cp1251' at line 5
mysql> -- а вот так для innodb работает :)
mysql> create table tst_innodb (
    ->   uid int not null,
    ->   msg_id int auto_increment,
    ->   primary key (msg_id, uid)
    -> ) engine = innodb default character set = cp1251;
Query OK, 0 rows affected (0.00 sec)

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

5   голосов , оценка 4.2 из 5