![]() |
Модераторы: skyboy |
![]() ![]() ![]() |
|
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Добрый день,
Задача: Есть таблица с данными: tbNum +----+ | id | +----+ | 1 | | 2 | | 4 | | 5 | | 6 | | 7 | +----+ id - ПЕРВИЧНЫЙ КЛЮЧ (т.е. Циферки которые лежат в данной таблице неповторяющиеся ) Уникальные) Как видим в таблице есть числа, НО эти числа идут не по-порядку, ПРОПУЩЕНО ЧИСЛО 3 !!! Другими словами число 3 в данной таблице есть минимальное свободное число! ТЕПЕРЬ ВОПРОС! Как сформировать правильно запрос в MySQL чтобы получить такое минимальное свободное число? Заранее, всех благодарю! |
|||
|
||||
skyboy |
|
||||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
и что? если id - первичный ключ, то это вполне нормально. зачем тебе туда чего-то вставлять? Добавлено через 5 минут и 59 секунд так уж и быть, вот запрос:
Добавлено через 7 минут и 4 секунды но если ты планируешь после удаления записей забивать вновь добавляемые с коррекцией значения id, то я хочу тебе сказать: так делать нельзя. заимеешь проблем. |
||||
|
|||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
К сожалению, пример не работает
![]() |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
да. "+1" было лишним.
Добавлено через 31 секунду работает. но неверно. |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Мой дорогой друг, вы для какой версии MySQL пишете этот код?
|
|||
|
||||
muzer |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
В случае когда пропусков нет вернётся максимальный id + 1. |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
Volter, версия 5.1.19 или 5.2, вроде бы как(посмотрю завтра - код писал на работе)
А что, разве существуют другие версии? ![]() ![]() Добавлено через 1 минуту и 59 секунд muzer, лаконичнее и без подзапросов ![]() ![]() |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
БЛАГОДАРЮ muzer и skyboy за содействия!
![]() Это сообщение отредактировал(а) Volter - 17.4.2007, 01:39 |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Товарищи!
Вопрос не до конца вообщето решили мы ![]() Допустим, у нас есть таже таблица, но с другой последовательностью данных: tbNum +----+ | id | +----+ | 3 | | 5 | +----+ По сути, запрос должен вернуть число 0, а не число 4, как возвращает данный код:
Что нужно приписать еще в SQL-запросе чтобы полностью удовлетворять данную проблемку? ![]() |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
Добавлено через 1 минуту и 46 секунд мой запрос должен идти после первого запроса(оператор union используется). Вместо UNION лучше даже использовать UNION ALL Добавлено через 2 минуты и 30 секунд Volter, открой страную тайну: на кой ляд тебе шаманство с primary key? |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
SkyBoy, Я вот рылся рылся в книге Полья Дюбуа "MySQL The definitive guide to using, programming, and administering MySQL databases", и не нашел грамотного AUTO_INCREMENT. В том смысле что этот AUTO_INCREMENT при добавлении строки просто в тупую увеличивает число не анализируя содержимое того атрибута к которому оно было присвоено. Т.е. Будет набор такой: tbNum +----+ | id | +----+ | 3 | | 5 | +----+ При добавлении новой записи в таблицу, параметр AUTO_INCREMENT создаст число 6, но разве это рационально, в том смысле что есть пустующие строки 0,1,2,4? И еще один небольшой вопрос, можно ли при создании таблицы прописать какой либо код в атрибут? т.е. создать код который автоматически при добавлении записи в таблицу, находит минимальное свободное число в данном атрибуте и присваивает его. Заранее благодарю, skyboy |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Да и вот еще кое чего:
Вот запрос на существовании данных в табличке. mysql> SELECT * FROM tbNum; +----+ | id | +----+ | 3 | | 5 | +----+ 2 rows in set (0.00 sec) А вот тот самый запрос, который непашет почемуто. ![]() mysql> SELECT t0.id,(temp.min_id-t0.id) difference -> FROM tbNum t0 -> INNER JOIN -> ( -> SELECT t1.id as id,min(t2.id) as min_id -> FROM tbNum t1 -> CROSS JOIN tbNum t2 -> WHERE t2.id> t1.id -> GROUP BY t1.id -> ) temp -> ON temp.id = t0.id -> WHERE temp.min_id- t0.id>0; ERROR 1064: You have an error in your SQL syntax. Check the manual that corresp onds to your MySQL server version for the right syntax to use near 'SELECT t1.id as id,min(t2.id) as min_id FROM |
|||
|
||||
skyboy |
|
||||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
а потому что подзапросы появились не сразу. Далеко не сразу. А версию используемого сервера ты так и не назвал, так что выводы не из чего делать. Надеюсь - пока что.
Но ведь строки сами по себе никуда не ушли?! Их удалили. А если на них(на записи в этих "строках") ссылались другие таблицы, то что лучше - пусть ссылаются на несуществующие данные и, скажем, inner join такие ситуации скроет, а left join отобразит, или лучше создать "в том месте" записи, никакого отношения к связанным данным не имеющие? Именно в виду такой политики безопасности, фраза
с приведенным примером не совсем верна. AUTO_INC отталкивается не от последнего значения в поле таблицы, а от "внутренного" счетчика, связанного с таблицей - благодаря этому после любого добавления/удаления строк, на вновь добавляемую строку(как на значение ключа) друие таблицы в принципе ссылаться не могут, потому как значение автоинкрементного поля во вновь создаваемой записи уникально. И мой тебе совет: не надо "переть" против этого механизма. Заимеешь скрытых граблей, а выиграть - и в чем не выиграешь. Ни в скорости(ключам на собственно значения плевать), ни в объеме(тип данных тот же - места занимают столько же). Есть такая вещь, как триггеры. В MySQL появились только в 5-й версии. |
||||
|
|||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
НебесномуМальчику мои особые благодарности, сразу видно начитанный в данной области человек, не то что некоторые на форумах!
SkyBoy, у меня к тебе несколько вопросов, ты уж извини я только начал изучение, а ты я гляжу уже давно знаком с SQL, если не откажеш, ответь:
Это сообщение отредактировал(а) Volter - 17.4.2007, 22:54 |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
не надо искажать мой ник. и переводить не надо. всю поэзию убил переводом ![]() доводилось плотно работать и рассматривать вблизи. "Жить захочешь - не так раскорячишься"(С) "Особенности национальной охоты" К твоему сожалению, я вполне обходился в работе английской версией мануала на dev.mysql.com: MySQL 5.0 Reference Manual и локальной версией справки, идущей в комплекте в дистрибутиве mysql(если только не заимел "обрезку" какую вроде как в Денвере) вот полный список манов для разных версий(заметь, что для <5 версий есть и русская версия) |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Огромное тебе спасибо, SkyBoy!
Там еще било несколько вопросов ![]()
Заранее, спасибо, вот дотяну до 100 постов, вляплю тЯбе огромный +! Это сообщение отредактировал(а) Volter - 17.4.2007, 23:11 |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
скорее всего, будет переполнение. но не часто бывают случаи с 2 миллиардами записей в таблице. Даже когда бывают - можно наваять составные ключи, первая часть которого будет автоинкрементной, а вторая - обновляться триггером при вставке новой записи... или перейти к строковым ключам неограниченной длины(потенциально скорость ниже) или ещё чего. Возможно - пересмотреть структуру БД на предмет адекватности. Если ты имеешь в виду проблему, что после очистки БД счетчик автоинкремента не сбрасывается, то такая конструкция:
но надо протестировать - такую конструкцию использовать не доводилось, могу ошибаться ![]() ![]() |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Я имелл ввиду что хотелось бы чтобы AUTO_INCREMENT был более рационален в добавлении индекса.
Согласись, что если б, AUTO_INCREMENT добавлял не какоето число из таблицы + 1, а анализировал свободные места то весьма рациональнее былобы с точки зрения, экономии памяти и упорядоченности индексов. Там еще било несколько вопросов ![]()
Вот дотяну до 100 постов, вляплю тЯбе огромный +! ![]() |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
"затыкания" дырок вообще не должно быть по моему мнению. приведенный мною запрос работает у меня на 5.2(выяснил-таки версию). приведенный muzer'ом запрос должен работать и на более ранних версиях(только добавить "мой" union для "первой" записи) и имена полей, и псевдонимы. только подчеркну - в обратных апострофах(что на одной кнопке с буквой "Ё" находится). А делаю это так потому, что в такой форме имена таблиц и полей никак не перепутаются с зарезервированными словами("SELECT group FROM select" будет тебе ругаться при выполнении, даже если у тебя есть таблица SELECT с полем, названным "group" ) и с функциями(можно использовать поле max и СУБД не будет путать это обращение с агрегирующей функцией). А в кавычках пишутся только строковые литералы ;) |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
![]() Все ЗАПИСАЛ, Все на ус намотал! Респект SkyBoy! |
|||
|
||||
skyboy |
|
||||||||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
видимо, объяснение про связанные таблицы ты не понял... смотри, есть таблица people:
есть таблица phones - номера телефонов
есть таблица people_phones, в которой хранятся соответствия между людьми и номерами телефонов(у нескольких людей могут быть одинаковый номер телефона - супруги, например; у одного человека может быть несколько телефонов - рабочий, домашний, мобильный...)
представь, что каким-то образом запись о человеке с номером 4 была удалена из таблицы people, а вот из people_phones записи, связанные с этим человеком, не удалили. Что произойдет, если "инетеллектуальный auto_increment" создаст нового человека не с idman, скажем, 25(потому что последнее ещё не использованное число), а со значением 4, потому что у нас так "окно"? Правильно, только что "созданный" человек сразу же "обретет" телефоны, к которым не имеет ни малейшего отношения. а представь, что такая бага вылезет не во время тестирования(когда данные набиваются "от балды"), а в процессе эксплуатации системы. И что - как ты отделишь потом "правильные" данные от "неправильных"? Все придется удалять? Ради сомнительного выигрыша в максимальном значении первичного ключа, получаешь очень неприятную проблему. Так смысл танцевать с бубном? |
||||||||
|
|||||||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
Что так агрессивно то?
![]() Я прекрасно понимаю связи таблиц, и во время удаления такого пользователя удалю и связи с ним. Вот допустим: people +-------+------+ | idMan | SNSn | +-------+------+ | 1 | ФИО | | 2 | ФИО | | 3 | ФИО | | 4 | ФИО | +-------+------+ phones +----------+--------+ | idPhones | number | +----------+--------+ | 1 | 464646 | | 2 | 468964 | | 3 | 777777 | | 4 | 577567 | | 5 | 675577 | | 6 | 655666 | +----------+--------+ people_phones +-------+---------+ | idman | idphone | +-------+---------+ | 1 | 3 | | 1 | 6 | | 2 | 1 | | 3 | 2 | | 3 | 4 | | 3 | 5 | | 4 | 2 | +-------+---------+ Как видим, мы имеем 4 пользователей, 6 номеров телефонов. Пользователь с idMan=1 имеет номероки 777777 и 655666 Пользователь с idMan=2 имеет номерок 464646 Пользователь с idMan=3 имеет номероки 468964, 577567 и 675577 Пользователь с idMan=4 имеет номерок такой же как и у пользователя idMan=3 т.е. 468964 Удаляем пользователя idMan=3 и связи с ним так: people +-------+------+ | idMan | SNSn | +-------+------+ | 1 | ФИО | | 2 | ФИО | | 4 | ФИО | +-------+------+ phones +----------+--------+ | idPhones | number | +----------+--------+ | 1 | 464646 | | 2 | 468964 | | 3 | 777777 | | 4 | 577567 | | 5 | 675577 | | 6 | 655666 | +----------+--------+ people_phones +-------+---------+ | idman | idphone | +-------+---------+ | 1 | 3 | | 1 | 6 | | 2 | 1 | | 4 | 2 | +-------+---------+ Теперь добавляем пользователя с помощью, как ты там назвал мою идею ), - "инетеллектуальный auto_increment" ) И получаем это: idMan=3 Это НОВЫЙ ПОЛЬЗОВАТЕЛЬ с идом 3 а не 5 как бы сделал AUTO_INCREMENT, и я знаю не надо было мне впервый раз говорить, - что если мы все удалим и создадим запись в people то AUTO_INCREMENT присвоил бы 5, не на столько я туп, я знаю что ведется отдельная таблица для ИНКРИМЕНТИРОВАНИЯ столбца ) people +-------+------+ | idMan | SNSn | +-------+------+ | 1 | ФИО | | 2 | ФИО | | 3 | ФИО | | 4 | ФИО | +-------+------+ # Номерки теже, зачем их удалять ) phones +----------+--------+ | idPhones | number | +----------+--------+ | 1 | 464646 | | 2 | 468964 | | 3 | 777777 | | 4 | 577567 | | 5 | 675577 | | 6 | 655666 | +----------+--------+ # И связей старых нет для старого пользователем который у нас был под idMan=3 people_phones +-------+---------+ | idman | idphone | +-------+---------+ | 1 | 3 | | 1 | 6 | | 2 | 1 | | 4 | 2 | +-------+---------+ Я не прав? ![]() Это сообщение отредактировал(а) Volter - 18.4.2007, 00:14 |
|||
|
||||
muzer |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
К сведению собравшихся - есть ещё тип bigint. Если делать unsigned, то максимум - 18446744073709551615
![]() ![]() Использование памяти, а точнее сказать дискового места, здесь совершенно не причём. Свободное место MySQL и так анализирует, и внутри своих файлов описанные вами правила пытается соблюдать. Что же касается значений автоинкремента, то как уже skyboy неоднократно сказал, они должны быть строго уникальны, это гарантия правильности содержащихся в бд данных. При частых удалениях из таблицы, полезно иногда выполнять запрос OPTIMIZE TABLE table_name - он как раз перестраивает таблицу таким образом, чтобы данные и индекс были упорядочены и не занимали лишнего места. А вот запись новых строк с ранее удалёнными значениями автоинкремента совершенно не гарантирует вам того же. |
|||
|
||||
Volter |
|
||||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
MUZER, не надо писАть лиш бы только писАть )
Знаем мы тут все про bigint unsigned!
И эт мы тож знаем, просто задайтесь вопросом, красивого подхода к коду, не просто написать, а красиво написать!
Да, а если вы заранее непродумали ТРИГЕРЫ(как мне стало о них известно от SkyBoy, вечная слава ему!) на удаление или изменение данных и у вас есть Вторичные(Внешние) ключи на таблицу в которой Вы провели OPTIMIZE TABLE? Или вы выполнили OPTIMIZE TABLE а не поправили Вторичные ключи в других таблицах ссылающиеся на данную? Этож верный путь к ошибке! ![]() |
||||
|
|||||
muzer |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 387 Регистрация: 31.8.2006 Репутация: 30 Всего: 31 |
Полный бред.
|
|||
|
||||
SelenIT |
|
|||
![]() баг форума ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3996 Регистрация: 17.10.2006 Где: Pale Blue Dot Репутация: 6 Всего: 401 |
К Вашему сведению, красиво написать можно и глупость ;).
Каким образом? Проясните, если не затруднит, для тугодумов вроде меня... -------------------- Осторожно! Данный юзер и его посты содержат ДГМО! Противопоказано лицам с предрасположенностью к зонеризму! |
|||
|
||||
skyboy |
|
|||
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 41 Всего: 260 |
сам-то - чего агрессивный такой? ![]() К слову о триггерах. У них есть несколько(на мой взгляд) существенных недостатков: 1. только два на каждое действие(в MySql версии 5.1) - так что при разработке в процессе коррекции логии возможно придется часто менять содержимое, что чревато внесением ошибок. Да и триггеры, описанные разработчиками двух скриптов на одну таблицу будут конфликтовать - придется разруливать вручную. Мне больше нравится механизм в InteRBase/FireBird, где возможных триггеров намного больше, а порядок задаешь самостоятельно. 2. скорость работы ниже чем у foreign keys. Но порою foreign keys не позволяет реализовать кое-что, что вполне работает на триггерах(на языке крутится пример удаления из таблицы, моделирующей дерево, родителя вместе с потомками, но я не помню, где происходили события - на InteRBase или на MYSQL). Так что сильно увлекаться триггерами, пожалуй, не стОит ![]()
НЕТ, не путь. А если и путь - то к светлому коммунизму, а не к ошибке. Как мне подсказывает ман, optimize table - это перестройка индекса(переупорядочивание) и физическое перемещение данных, чтоб избежать из кластеризации("разлития" по всему файлу-контейнеру). Т.е. все значения(в т.ч. и автоинкрементные) и их типы(логика) остаются неизменными - меняется только хранение этой логики в памяти для ускорения доступа. И, возможно, уменьшения размера(возможно, имеется в виду записи индексов, отсуствующие в таблице, которые можно удалить - неспроста семантика optimizre такоВА, что сначала вызывается repair!). |
|||
|
||||
Volter |
|
|||
Новичок Профиль Группа: Участник Сообщений: 14 Регистрация: 16.4.2007 Репутация: нет Всего: нет |
skyboy, я тебе очень благодарен, за твою лояльность по отношению ко мне.
Огромное тебе спасибо! Ты терпелив к вопросам человека который взялся за SQL, просто ОГРОМНОЕ тебе спасиб! Великая глупость заключается не в том, что по незнанию задают глупость, а в том чтобы смеяться над тем кто задает эту глупость по незнанию. Norbert Wiener Добавлено через 2 минуты и 19 секунд Жизнь тоже глупость по своей сути, если разобраться в деталях, но живем же. ![]() |
|||
|
||||
Glip |
|
|||
Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 473 Регистрация: 30.12.2006 Репутация: 3 Всего: 18 |
а что мешает использовать unsigned int - 4294967295 или даже unsigned bigint - 18446744073709551615? http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html выбор типа и размера поля определяется при анализе задачи. если вам не хватает unsigned bigint стоит задуматься о смене субд или пересмотреть структуру данных Это сообщение отредактировал(а) Glip - 18.4.2007, 09:41 |
|||
|
||||
SergeBS |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
2All
Вот, елы-палы, нашли занятие. Маленькое упражнение в арифметике: пусть есть 100 юзеров, работают 24 часа в сутки 365 дней в году, вставляют по 10 записей в минуту. Вопрос - когда иссякнет AUTO_INCREMENT у int / bigint? А попытки заполнять "дыры" у этих полей - верный способ заиметь проблемы потому, что если эту "дыру" вычислять, то любые 2 юзера получат одно и то же значение "дыры", пока ее кто-то не заполнит. И соответственно "заполнят" ее по очереди. А с учетом commit/rollback все становится еще печальней. И никакие "специальные" поля от этого не спасут по причинам, аналогичным тем, что возникают у FoxPro, например, при попытке соорудить на нем многопользовательское приложение. Volter, Вместо "фантазии на вольную тему" рекомендую почитать классиков (от SQL), а не изобретать велосипед с квадратными колесами, считая что он красив. Тем более что новичкам это просто предписано: изучать предмет по докам, а не заниматься изобретательством. Добавлено через 2 минуты и 14 секунд muzer,
Исключительно верно подмечено. Добавлено через 6 минут и 20 секунд 2All: Если кто-то таки желает избавиться от "дыр", то единственное решение - отрубить всех юзеров на время этой процедуры и накатать соответствующие скрипты, чтобы сам сервер перемещал на "дыру" следующую за ней запись и т.д. Привда при больших таблицах - успеете уйти к окончанию работы скрипта на пенсию ![]() |
|||
|
||||
JavaCraft |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
При 10000 пользователей (что маловато будет для Internet-ориентированной системы) INTEGER иссякнет через 5 лет. Если они творческие личности и склонны к частым изменениям записей(контента), то автоинкремент иссякнет очень быстро. Использование везде и всюду BIGINT снижает производительность. Если конкретный идентификатор резервировать за конкретным юзером, то они никак не смогут одновременно использовать одно и тоже значение. Кроме того это резервирование выполняется в целях контроля и безопасности, для учета кто и что вводил. Проще, повесить на триггер AFTER DELETE сохранение удаленного идентификатора в небольшой таблице резерва, а потом, если резерв есть, его оттуда брать. Если в момент сохранения произойдет сбой или атомная война, то максимум что произойдет это потеря одного единственного удаленного значения, что никак не скажется на базе в целом. |
|||
|
||||
SergeBS |
|
||||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
JavaCraft,
А ежели подумать? Здравый смысл применить?
Еще раз: любая попытка вычисления/получения уникального значения идентификатора из приложения, а не путем формирования его сервером, ПРИНЦИПИАЛЬНО источник проблем. Хотя бы по той причине, что приложение не может определить (не)успешность этой операции и произвести откат. |
||||||
|
|||||||
JavaCraft |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
О приложении и речи нет. Всё делает исключительно сервер. Поле автоинкрементное, но если вставлять запись с инициализированным не NULL значением, то MySQL не выполняет автоинкремент, а использует то значение, которое ему дали. Это значение берется из таблицы резерва, которая хранится также на сервере. Выполняет все это хранимая процедура, тоже на сервере. Такая же процедура сбрасывает идентификаторы в резерв, после удаления записей. Пользователь имеет доступ к базе исключительно через хранимые процедуры и ничем не может навредить базе. А Вы, как я полагаю, предпочитаете давать юзеру права выполнять SQL запросы INSERT,DELETE,UPDATE... из приложения. ![]() |
|||
|
||||
Бонифаций |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 827 Регистрация: 15.9.2005 Где: Brisbane Репутация: 20 Всего: 40 |
Вы полагаете выборка значения из таблицы будет быстрее операции с бигинтом? Добавлено через 1 минуту и 40 секунд Кроме того при массированом использовании триггеров с хранимками говорить о производительности вообще трудно. Это же интерпретируемые языки которые будут дергаться при любом изменении записи. Добавлено через 4 минуты и 51 секунду
10000 одновременно работающих пользователей ![]() Добавлено через 7 минут и 9 секунд PS Если вам мало int/bigint - используйте функцию UUID(). Она для таких целей и создана -------------------- Бонифаций. |
||||
|
|||||
JavaCraft |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
В нормальных условиях не быстрее, но BIGINT требует в два раза больше дисковой и оперативной памяти. Кроме того, сказали А, должно сказать и В. Во всех таблицах где мы ссылаемся на эту таблицу нам придется перейти на BIGINT. Про индексы забыли? Они тоже удвоятся. Если памяти не хватит, то таки ДА будет медленнее. Для меня лишние 32Гиг на каждую таблицу и каждое ссылочное поле, приемлемы только в случае если другого пути нет. А выборка из маленькой таблицы, к томуже закэшированной в памяти, выполняется очень быстро.
На любом, хоть на P1 133Mhz 64RAM. Тут не в нагрузке дело и не в одновременности, а в количестве и качестве "писателей". Достаточно просто раз в 1-10 секунд подключаться и добавлять запись. Ну не при любом, а при вполне конкретном. AFTER DELETE, BEFORE INSERT А соотвествующие SP вызываются по мере необходимости. И они компилируются один раз, а не интерпретируются каждый раз, если только Вы под интерпретацией не имеете в виду внутреннюю реализацию скомпилированного кода. Но это же мелочи. Куда тяжелее и дольше взаимодействовать с внешней бизнес логикой. Это сообщение отредактировал(а) JavaCraft - 3.5.2007, 01:50 |
||||
|
|||||
SergeBS |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
JavaCraft,
Немножко посчитаем. Int - 8, bigint - 16 байт. 32 Гб/8 = 4 Г записей. Если в записи 100 байт - таблица - 400 Гб. 10 таблиц - 4 Тб. Ну в 2 раза меньше, если поле просто добавить. Непринципиально. Может сказочки в другом месте будешь рассказывать?
Опять бред. От незнания основ. |
||||
|
|||||
JavaCraft |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
И что вы уже этим хотели сказать? 32Гб это увеличение расхода памяти на 4Г проиндексированных записей состоящих из 1 поля. Поуважительнее плиз, просьба не хамить. Такие реплики признак непрофессионализма, а мнение непрофессионала меня не интересует. |
|||
|
||||
SergeBS |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
JavaCraft,
Если не понял, то объясняю: я прикинул размер БД, у которой добавление 1 поля int или изменение с int на bigint увеличивает размер таблицы на 32 Гб. Как автор описал.
А нука подробнее, пример в студию. Как это вычислялось и что за таблица? Только не надо уползать в сторону полнотекстового поиска и т.п. Речь идет об int/bigint. |
|||
|
||||
Бонифаций |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 827 Регистрация: 15.9.2005 Где: Brisbane Репутация: 20 Всего: 40 |
2JavaCraft:
"Валик-джан, я тебе один умный вещь скажу, только ты не обижайся", - Вы говорите о миллиардах записей, и приводите P1 133Mhz 64RAM в качестве железа. - Вас страшит bigint, хотя заполнить обычный unsigned int автоинками еще никому не удавалось. По крайней мере на моей памяти. - вы говорите о компиляции хранимок/триггеров. Хотя на самом деле они хранятся в в таблице mysql.proc просто как строки, а кешируются как деревья, и исполняются обходом аттрибутного дерева в памяти. Это чистой воды интерпретация. Иначе вам придется называть и питон и перл компилируемыми языками. Не обижайтесь, но Вы теоретик. Это сообщение отредактировал(а) Бонифаций - 3.5.2007, 13:57 -------------------- Бонифаций. |
|||
|
||||
JavaCraft |
|
||||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
На той железке у меня был Web-сайт и летала база с таблицами 8000000 записей, правда всё было на MyISAM, только для чтения и посетителей не много. Этот гратеск не для показа на чем будет крутиться эта база (такое железо сейчас трудно найти), а чтобы было понятно, что от нагрузки в единицу времени тут ничего не зависит.
В моей задаче UNSIGNED INT будет заполнен очень быстро (чисто теоретически). не обижаюсь А вообще парню нужно было решение как заполнить пробелы в идентификаторах и я его кажется дал. Причем это лучшее решение в данной постановке вопроса. Я не утверждаю что оно лучше чем автоинкремент, это несравнимые и совсем разные вещи. Это сообщение отредактировал(а) JavaCraft - 3.5.2007, 16:55 |
||||
|
|||||
SergeBS |
|
||||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
Бонифаций,
JavaCraft не теоретик, а обычный "WEB-дизайнер", поперший в СУБД. Не первый и не последний. JavaCraft,
В классическом понимании это не база, а куча разрозненных таблиц. На чем и попадаются, пытаясь кислое с красным сравнивать.
А вообще если в чем-то не разбираешься совсем, так лучше не советовать. Поскольку получается "лучшее лекарство от насморка - гильотина". |
||||
|
|||||
JavaCraft |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
Ну ну. Можно подумать твои посты по всем форумам можно назвать содержательными... Везде, где твою писанину встречаю, вижу только хамство и обсерательство. Подумай на досуге, может тебе к доктору нужно сходить? |
|||
|
||||
SergeBS |
|
|||
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1111 Регистрация: 10.6.2005 Где: Владимир Репутация: 2 Всего: 22 |
JavaCraft,
Я не хамлю. Нет такой привычки. Просто я на основании своего опыта достаточно быстро определяю что из себя представляет собеседник. И вместо фантазирования использую факты и доки. В отличие от. Когда новичок предлагает свое "гениальное" решение, которое ПРИНЦИПИАЛЬНО неверно и приведет к проблеме, то этот новичок неправ по крайней мере дважды. |
|||
|
||||
JavaCraft |
|
|||
Шустрый ![]() Профиль Группа: Участник Сообщений: 139 Регистрация: 8.2.2007 Репутация: 0 Всего: 1 |
||||
|
||||
![]() ![]() ![]() |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | MySQL | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |