Генерация собственного уникального идентификатора записи

Тема в разделе "Базы данных", создана пользователем lonejan, 28 июл 2013.

Статус темы:
Закрыта.
Модераторы: latteo
  1. lonejan

    lonejan Постоялец

    Регистр.:
    7 фев 2008
    Сообщения:
    110
    Симпатии:
    10
    Доброго времени суток, комрады.

    Стоит следующая задача: нужно генерировать для каждой записи в БД уникальный ИД, по которому так же можно определить к какой таблице он относится.

    Генерировать буду хранимой процедурой MySQL, чтобы не создавать по два запроса в PHP. ИД будет настраиваемый по длине и состоит из латинский букв и чисел (1-0 A-Z a-z), причем первых два символа это будет ИД таблицы, например PR0001Qf, PR0001Qg, PR0001Qh. От генерации по UUID() отказался т.к. слишком большая длина, а UUID_SHORT() имеет ограничение уникальности при server_id > 255 и другие недостатки.

    1. Но, что же получается, мне что нужно перед каждым INSERTом лочить таблицу на чтение и запись? Ведь теоретически в промежуток времени, между началом генерациии нового ИД и вставкой его в таблицу, второй клиент может так же попробовать сгенерировать новый ИД, который будет не уникальным.

    2. Как получить идентификатор вставленной записи? Как вариант вижу делать все вставки через хранимые функции MySQL, но не хочется.

    Интересуют так же ваши мысли по поводу.
     
  2. allseo

    allseo Создатель

    Регистр.:
    26 июн 2013
    Сообщения:
    38
    Симпатии:
    10
    Вероятность совпадения ничтожно мала. Если это не архимегаважная система, от ошибки в которой пострадают сотни людей, не стоит даже переживать по этому поводу. Чтобы таймстампы и генерируемые по ним значения совпали... В конце концов, можно проверять айдишник на уникальность непосредственно перед записью. Но с разрастанием базы эти проверки будут создавать тормоза...
    И почему предпочитаете функциям процедуры? Раз нужно, то почему не использовать?
     
  3. lonejan

    lonejan Постоялец

    Регистр.:
    7 фев 2008
    Сообщения:
    110
    Симпатии:
    10
    Функции, не процедуры, ошибся.
    Но все же вероятность коллизии при определенной нагрузке есть, привык делать на совесть.
    И да, пока будет выбираться MAX(id), на большой таблице ее нужно лочить R/W, а это неудобства. В всяких 1С так и есть, но для вэб проекта не подходит(
    Если бы как-то переопределить работу стандартного auto_increment.
     
  4. olultur

    olultur Создатель

    Регистр.:
    24 фев 2013
    Сообщения:
    19
    Симпатии:
    1
    Правильный подбор индексов должен свести к минимуму тормоза.
     
  5. allseo

    allseo Создатель

    Регистр.:
    26 июн 2013
    Сообщения:
    38
    Симпатии:
    10
    К уникальным ключам индексацию прикручивать? По-моему, это уже оверхед. Разве что для кэширования, и то, оно того стоит лишь если сильно припечёт.
     
  6. lonejan

    lonejan Постоялец

    Регистр.:
    7 фев 2008
    Сообщения:
    110
    Симпатии:
    10
    Это будет ПК, зачем еще индексы? Имелись ввиду тормоза при нагрузке, если будет 100 человек онлайн, то сотый будет ждать пока сервер 99 раз проверит maxid().
     
  7. olultur

    olultur Создатель

    Регистр.:
    24 фев 2013
    Сообщения:
    19
    Симпатии:
    1
    Ну хорошо, тогда правильный подбор железа и СУБД должен спасти "гиганта мысли".
    Без проектирования не обойтись.
     
  8. esche

    esche

    Регистр.:
    9 авг 2009
    Сообщения:
    360
    Симпатии:
    243
    А чем не угодил autoincrement с первичным ключом по двум полям?
    id_table
    id_record

    В зависимости от указанного id_table будет увеличиваться id_record

    http://dev.mysql.com/doc/refman/5.5/en/example-auto-increment.html - см пример про animals:
    Код:
    CREATE TABLE animals (
        grp ENUM('fish','mammal','bird') NOT NULL,
        id MEDIUMINT NOT NULL AUTO_INCREMENT,
        name CHAR(30) NOT NULL,
        PRIMARY KEY (grp,id)
    ) ENGINE=MyISAM;
     
  9. Maverik

    Maverik Писатель

    Регистр.:
    30 сен 2013
    Сообщения:
    8
    Симпатии:
    0
    можно еще проще
    собственный праймари кей вида UNIX_TIMESTAMP(NOW()) + номер таблицы. :)

    совпадет только если обратиться одновременно к двум записям, созданным именно в этих двух таблицах в одну и ту же миллисекунду...
     
  10. lonejan

    lonejan Постоялец

    Регистр.:
    7 фев 2008
    Сообщения:
    110
    Симпатии:
    10
    Читайте первый пост, это не вариант, и там написано почему.
     
Статус темы:
Закрыта.