Форум сайта python.su
Добрый день! Я не так давно начал работу с sqlite3. У меня python3.4 и sqlite 2.6.0 (sqlite3.sqlite_version показывает ‘3.6.20’, не знаю, в чем разница).
Проблема в следующем. Есть таблица в 12 колонок и почти 32.000 строк. В качестве идентификатора использую колонку NO, она содержит номера строк. ID Autoincrement, как я понял, мне не подходит, потому что там везде уникальный ID для всех строк, в том числе, удаленных, а мне нужно, чтобы было строго +1 для всей нумерации.
Когда я удаляю строку, мне нужно перенумеровать все строки в колонке NO. Для этого использую (условно):
lst = [(x,) for x in range(31889)] dbc.executemany('update TEST set NO=?',lst)
Офлайн
vanvanovЭто неправильный способ. В таблице должен храниться только порядок записей, а номера должны назначаться при выборке в соответствии с порядком записей. Поэтому ничего не надо перенумеровывать; главное, чтобы порядок записей сохранялся. И id и порядок должны быть разными полями, так как id не обязан быть в каком-то порядке, он только за уникальность отвечает. А дальше, когда ты выбрал все записи, ты их нумеруешь.
Когда я удаляю строку, мне нужно перенумеровать все строки в колонке NO.
Отредактировано py.user.next (Фев. 5, 2017 02:19:54)
Офлайн
py.user.next
А по какому критерию sqlite хранит порядок записей - по времени добавления? А если, например, есть записи 0-500, и нужно будет вставить запись как раз между 495 и 496? А если нужно сделать SELECT для записей 300-350, как будет выглядеть запрос? Но даже если все это как-то можно утрясти, почему в принципе update такой адски медленный?
Офлайн
У вас какойто извращенный маниакальный метод садомазохизма закрученный на никрофилии!
Предположим вам нужно удалить строку таким методом что бы не нарушился порядок?
Ну так тем же апдейтом просто очистите дынные в етой строке - пусть останеться пустой но только с ижентификатором!
Просто пока у вас 32к записей - ето ничто! а вот когда вы решите каждый раз переиндексировать 3 лимона это уже будет интереснее!
В целом я не до конца верно вам ответил - но совершенно точно могу сказать что у вас ошибка на уровне структуру/запросов в бд!
Если вы более детально опишите структуру и задачу - возможно вам дадут совет как сделать “правильно”
з.ы. проблема совершенно точно не в sqlite !
Офлайн
vanvanovЭто твоя задача - сделать такое поле, отвечающее за порядок. Через него записи будут понимать, какая идёт раньше, а какая позже.
А по какому критерию sqlite хранит порядок записей - по времени добавления?
vanvanov495-ая может иметь номер 12345, 496-ая может иметь номер 56789, тогда запись между ними будет иметь номер (12345 + 56789) / 2.
А если, например, есть записи 0-500, и нужно будет вставить запись как раз между 495 и 496?
vanvanovОтсортируешь по полю порядка и возьмёшь записи с 300 по 350.
А если нужно сделать SELECT для записей 300-350, как будет выглядеть запрос?
vanvanovПотому что при каждом добавлении каждой записи ты переписываешь вообще все записи. То есть если ты добавляешь 10 новых записей, то ты 10 раз переписываешь всю таблицу базы данных. Быстро это или медленно, в любом случае это глупо и неэффективно.
почему в принципе update такой адски медленный?
Отредактировано py.user.next (Фев. 5, 2017 10:53:25)
Офлайн
Давайте начнем с того, какой смысл имеет номер записи в вашей задаче?
Офлайн
py.user.nextAutoincrement? Или несистемное?
Это твоя задача - сделать такое поле, отвечающее за порядок.
py.user.nextА именно? Каждый раз делать fetchall() и дальше производить манипуляции со списком? У меня это получается медленнее, чем средствами самой БД. И больше нужно кода.
Отсортируешь по полю порядка и возьмёшь записи с 300 по 350.
PooHБД представляет собой словарь. Для него написана обертка, позволяющая делать поиск (кстати, LIKE не поддерживает кириллицу, но, видимо, это отдельная тема), а также навигацию по номеру записи. Естественно, если в БД 10 записей, то GUI должен отображать, например, “Записи 0-9” или “Записи 1-10” и предлагать переход между ними. Т.е. все завязано на номере.
Давайте начнем с того, какой смысл имеет номер записи в вашей задаче?
py.user.nextНу, я так и думал. Но разве это не архитектурная проблема sqlite? А если все же требуется обновить всю колонку? Создавать новую таблицу, переносить в нее данные с учетом новой колонки, а старую таблицу удалять?
Потому что при каждом добавлении каждой записи ты переписываешь вообще все записи. То есть если ты добавляешь 10 новых записей, то ты 10 раз переписываешь всю таблицу базы данных. Быстро это или медленно, в любом случае это глупо и неэффективно.
Офлайн
vanvanovСвоё поле без всякого автоинкремента. Автоинкремент у тебя должен стоят на поле id, которое идентифицирует каждую запись. Почему своё поле - потому что у тебя там между разными номерами должно быть место, куда можно вставить запись, и не одну.
Autoincrement? Или несистемное?
vanvanovСортируешь и берёшь 350 записей, из них отбрасываешь 300. Да и sqlite допускает указание “limit 299,50”, так что даже ничего отбрасывать не надо.
Каждый раз делать fetchall()
vanvanov
кстати, LIKE не поддерживает кириллицу
sqlite> select prof from ccpview where prof like '%програ%';
prof
Оператор ПК, программист, системный администратор
Инженер-программист
Оператор, системный администратор, программист, техник ЭВМ
Техник, программист
Инженер-программист
Системный администратор, программист, лаборант-программист, web-программист
Инженер-программист, водитель-экспедитор
IT-инженер, системный администратор, инженер-программист
Программист, web-программист
Web-разработчик, web-мастер, программист
Администратор, программист, оператор
Инженер-программист
Инженер-программист
Системный администратор, IT-специалист, инженер, инженер-программист
Системный администратор, IT-специалист, инженер, инженер-программист, программист 1С
Инженер-программист, системный администратор
Инженер-программист
Системный администратор, программист
Веб-программист, IT-специалист
Инженер-программист
Веб-программист, верстальщик, веб-мастер, веб-дизайнер
Системный администратор, программист, лаборант-программист
Инженер-программист, системный администратор
Электромеханик, инженер-электроник, программист
Помощник эксперта по недвижимости, программист-стажер, разнорабочий
Техник-программист
Сайт-менеджер, системный администратор, IT-специалист, web-программист
IT-специалист, программист
Инженер-программист
Инженер-программист, системный администратор
Техник-программист
Инженер-программист
Лаборант-программист
Инженер-программист
Инженер-программист
Web-программист, инженер-программист, программист
Веб-программист, системный администратор
Специалист ИТ, программист
Экономист-программист
Инженер, техник-программист, проектировщик
Экономист, программист, менеджер
Техник-программист
Инженер-программист
Инженер-программист
Системный администратор, инженер-программист
Менеджер, программист
Инженер-программист
Инженер, программист
Системный администратор, инженер-программист
Инженер-программист
Программист-техник, программист-инженер, системный администратор
IT-специалист, программист, техник ЭВМ
Помощник программиста, электроник
Администратор базы данных, инженер-программист
Системный администратор, программист
Инженер-программист, системный администратор
Официант, программист, помощник
Системный администратор, программист
Системный администратор, программист, инженер-системотехник
Инженер-программист
Программист-разработчик программного обеспечения, программист 1С, системный администратор
Руководитель сектора социальных программ, специалист по работе с надзорными органами
Web-программист, верстальщик, web-дизайнер
Web-дизайнер, web-программист, SEO-оптимизатор
Информатик-экономист, программист, менеджер, системный администратор
Системный администратор, программист, IT-специалист
Инженер-программист
Экономист-программист
Дизайнер, верстальщик, программист
Системный администратор, программист, оператор ПК
Системный администратор, программист
Системный администратор, IT- специалист, программист, водитель
sqlite>
vanvanovЧто перезапись всех записей занимает время? Это проблема проектирования базы данных - когда требуется постоянная перезапись всех записей.
Ну, я так и думал. Но разве это не архитектурная проблема sqlite?
vanvanovМы тут говорим о чём-то абстрактном, приведи код. Может, там из-за кода тормозит всё, а ты на СУБД валишь. Но по текущим данным, когда при добавлении записи в таблицу все остальные записи должны переписываться, это звучит как-то не так, как будто ты не понимаешь, что делаешь. Так что и код там явно такой же, а значит и ошибки могут быть в нём алгоритмические. Обновить колонку ты можешь, но только раз на тысячу операций (что можно и подождать), а не раз на каждую операцию.
А если все же требуется обновить всю колонку?
Отредактировано py.user.next (Фев. 5, 2017 14:52:46)
Офлайн
vanvanovЭто, обычно, делают не так - задают сортировку и ограничивают вывод через LIMIT и OFFSET.
Естественно, если в БД 10 записей, то GUI должен отображать, например, “Записи 0-9” или “Записи 1-10” и предлагать переход между ними. Т.е. все завязано на номере.
Офлайн
py.user.nextlimit по умолчанию не задействован, перекомпилировать надо.
Да и sqlite допускает указание “limit 299,50”, так что даже ничего отбрасывать не надо.
py.user.nextОК, а найдется ли ‘Оператор’ по запросу ‘%оператор%’? Вроде, ICU решает эту проблему, но там тоже могут быть сложности при установке.
sqlite> select prof from ccpview where prof like ‘%програ%’;
prof
Оператор ПК, программист, системный администратор
PooHНу вот, смотрите.
Это, обычно, делают не так - задают сортировку и ограничивают вывод через LIMIT и OFFSET.
select NO from TEST order by NO limit 500 select TRANSLATION from TEST where NO=?
select TRANSLATION from TEST where NO=?
Офлайн