sadr0b0t / vkurse

Automatically exported from code.google.com/p/vkurse
0 stars 0 forks source link

Избавиться от методов findFreeId и insertWithNewID #5

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
Нужно убрать все методы findFreeID и insertWithNewID - 
вместо них использовать типы данных serial 
или bigserial для идентификаторов таблиц.

Из обсуждения в рассылке 
(http://groups.google.com/group/innofivt2010/browse_thread/thread/57dfbe66d5c24d
53):

>    В модель и во все сервисы xxxTable добавлен 
метод
>        public int findFreeID() throws TableException;
>    Метод позволяет найти свободный ID для 
добавления нового элемента.

Это не правильный подход как минимум по 3м 
причинам:
1. Это просто не удобно
2. Это требует делать дополнительный запрос 
к базе данных в той ситуации, когда можно 
обойтись одним
3. В многопользовательских системах с общей 
базой данных такой подход просто 
недопустим, т.к. если у вас будет два 
пользователя на 2х разных компьютерах 
добавлять записи в расписание (пусть даже 
для совершенно разных групп и даже 
совершенно не обзательно в одну и ту же 
секунду), они получат на входе одно и тоже 
значение для ID и того из них, кто нажмет 
кнопку "добавить" вторым, возникнет 
нелогичная с точки зрения пользователя 
ошибка "duplicate value for unique field" (или что-то типа 
того).

При этом решается проблема очень просто - 
нужно для столбца ID при создании всех 
таблиц указать тип данных serial или bigserial - 
аналоги int и bigint, только с автоматической 
нумерацией (это для PostgreSQL - для MySQL название 
типа данных может отличаться, но суть 
должна быть та же).

После этого для запроса INSERT можно 
указывать все значения стобцов, кроме ID - 
нужное значение база данных сгенерирует 
автоматически.

Сгенерированный таким образом ID можно 
потом получить обратно через специальный 
механизм JDBC-драйвера (при запросе нужно 
указать специальный параметр), но сейчас 
предлагаю с этим не заморачиваться и в API 
эту возможность не выностить (кстати, в 
PostgreSQL поддержка этой возможности 
появилась совсем недавно - в одной из 
последних версий).

>Метод  @Override public String toString()  переименован в  
public String toStringData()
>По поводу добавления новых данных и поиска 
свободного ID: метод int findFreeID() оставил, 
добавил
>public boolean insertWithNewID(ExamType item) throws TableException;
>При передаче объекта этому методу поле ID 
игнорируется и перед добавлением 
генерируется свободный ID.

Это абсолютно лишнее - неиспользуемые 
методы в публичном API только сбивают с 
толку. Откровенно говоря не уверен, как 
поведет себя база данных при ручном 
задании значения для serial - вполне возможно, 
что проглотит, а может бы и выдаст ошибку (и 
будет при этом права - у нее там для этих 
целей свои внутренние индексы есть и 
прочая кухня, в которую без лишней 
необходимости лучше не лезть). В любом 
случае, findFreeID() не нужен однозначно, а 
insertWithNewID без него ставится просто лишней 
сущностью, усложняющей код. Оставь просто 
старый insert(), игнорирующий ID и на этом 
остановимся.

Original issue reported on code.google.com by bender...@gmail.com on 23 Oct 2010 at 3:02

GoogleCodeExporter commented 9 years ago
Библиотеку изменил, убрал лишние методы, 
переделал insert - теперь он возвращает int ID 
добавленного объекта.
В данный момент необходимо изменить 
структуру БД на сервере, но сделать этого я 
не могу, т.к. phpPgAdmin на сервере в данный 
момент недоступен.
При изменении типов полей скорее всего все 
данные будут потеряны. Возможно, что будут 
порушены зависимости по ID, но такие данные 
проще полностью ввести заново. И очень 
маленькая вероятность, что при изменении 
типа поля изменений в данных не будет. При 
изменении типа поля на локальном MySQL 
(используемом для отладки) все данные были 
потеряны.

В данный момент жду восстановления 
работоспособности phpPgAdmin

Original comment by apx%phys...@gtempaccount.com on 24 Oct 2010 at 12:07

GoogleCodeExporter commented 9 years ago
Спасибо, очень хорошо.

По поводу сохранности существующих данных 
- вы можете выгрузить их в sql-файл из текущей 
базы данных и потом заново загрузить во 
вновь созданную (хотя сохранение 
целостности автоиндекса наверное все 
равно останется под вопросом).

Я думаю, лучше всего не морочиться с этим и 
ввести все данные заново - сами сильно не 
напрягайтесь - для внутренней проверки 
забейте несколько значений на один день. 
Остальное поручим тестеру веб-интерфейса - 
проверить процесс создания расписания 
через веб-браузер будет как раз кстати.

Original comment by bender...@gmail.com on 24 Oct 2010 at 1:13

GoogleCodeExporter commented 9 years ago
Обновлял структуру БД - никаких данных в 
базе на данный момент не было. Только одна 
запись в таблице examtypes, и та совершенно 
бессмысленная. Соответственно, сейчас 
таблицы совершенно пусты

Original comment by apx%phys...@gtempaccount.com on 9 Nov 2010 at 6:48

GoogleCodeExporter commented 9 years ago
P.S. также везде был изменен метод insert - 
теперь он возвращает int - ID добавленной 
записи, поле ID у добавляемого объекта 
игнорируется и генерируется базой данных

Original comment by apx%phys...@gtempaccount.com on 9 Nov 2010 at 6:58

GoogleCodeExporter commented 9 years ago
2 замечания.

1)Никогда-никогда не ломайте API без 
подтверждения от других групп. 
        У меня тут чуть сердце не треснуло, когда программа стала выдавать эксепшены methodnotforund на   редактировании списков.

2)
багрепорт - автоинкремент работает 
странно. Он начинает считать  с нуля.

То есть, с каждым добавлением он протсо 
прибавляет единицу. А поскольку там уже 
есть значения с ID>=3, то на этих ID выдается 
ошибка.

Original comment by Lockyw...@gmail.com on 14 Nov 2010 at 3:14

GoogleCodeExporter commented 9 years ago
>А поскольку там уже есть значения с ID>=3, то 
на этих ID выдается ошибка.

надо полагать, эти данные уже были 
добавлены ранее с заданным 
идентификатором - если почистить все 
таблицы и начать добавлять все данные 
заново, то проблема проявиться не должна. 
предлагаю именно это и сделать, чтобы не 
нарываться на лишние проблемы в процессе 
тестирования.

Original comment by bender...@gmail.com on 14 Nov 2010 at 3:31

GoogleCodeExporter commented 9 years ago
Вроде, теперь работает.

Original comment by Lockyw...@gmail.com on 22 Nov 2010 at 10:54