SQLite3

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

SQLite3

Сообщение arriah » 15.07.2018 15:43:34

Привет всем,

Никогда не разрабатывал базы данных с нуля, в основном работал на готовых. Но теперь понадобилось это сделать.
Вроде со всем разобрался, но остались некоторые воспросы. Суть в том, что надо создать грамотную структуру БД.

БД должна состоять из трех таблиц
Организация
Автомобили
Водители

У одной организации может быть несколько автомобилей - с этим понятно, организовываем связь один ко многим
За каждым водителем может быть закреплен 1 автомобиль, или на каждом автомобиле может быть только один водитель - вот в этом вопросе возникают сложности, ибо автомобиль может быть просто без водителя, типа стоит в парке и не работает.

Вот как мне организовать базу данных с внешними ключами и ненарушить целостность БД, чтобы выполнялись следующие условия:

1. Водителя можно удалить из базы данных
2. Водителя можно пересадить с одной машины на другую
3. Автомобиль можно перенести из одной организации в другую
4. Автомобиль может быть удален

Пока сделать такую структуру:
Код: Выделить всё
CREATE TABLE firms (
   FirmsID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   FirmsIndex VARCHAR (255) NOT NULL,
   FirmsAddress VARCHAR (255) NOT NULL,
   FirmsOGRN VARCHAR (255) NOT NULL,
   FirmsINN VARCHAR (255) NOT NULL,
   FirmsPhone VARCHAR (255) NOT NULL,
   FirmsDisp VARCHAR (50),
   Cars_ID INTEGER NOT NULL,
   FOREIGN KEY (Cars_ID) REFERENCES cars(CarsID));

CREATE TABLE cars (
   CarsID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   CarsName VARCHAR (50) NOT NULL,
   CarsNumber VARCHAR (50) NOT NULL,
   CarsLic VARCHAR (50) NOT NULL,
   CarsGrant VARCHAR (50) NOT NULL,
   Drivers_ID INTEGER NULL,
   FOREIGN KEY (Drivers_ID) REFERENCES drivers (DriversID));

CREATE TABLE drivers (
   DriversID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
   DriversFIO VARCHAR (100) NOT NULL,
   DriversPrava VARCHAR (50) NOT NULL);


Но что-то мне подсказывает что я сделал что-то неправильно, особенно с внешними ключами.
И как правильно в моем случае связывать машину с водителем или водителя с машиной?

В идеале должно работать так:
Механик выбирает из списка водителя и видит инфу о машине и организации, за которой закреплена машина.
Начальник колонны имеет право цволить водителя, закрепить машину за другой организацией и удалить машину.
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: SQLite3

Сообщение Снег Север » 16.07.2018 08:17:30

FOREIGN KEY в вашем случае приведет к тому, что при удалении записи из firms автоматически удалятся все связанные записи из cars и, соответственно, из drivers. Вам надо предусмотреть в коде аппликации, чтобы перед удалением изменить привязку автомобиля и водителя к другой записи, если удаление недопустимо. Можно придумать также встроенные процедуры и триггеры, чтобы по максимуму переложить работу на движок
SQLite. Что вам удобнее - решайте сами.

И, надеюсь, вы помните, что SQLite - это, принципиально, однопользовательская БД? А то есть любители ладить многопользовательские велосипеды на ее основе, а это не есть гуд. :)
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3039
Зарегистрирован: 27.11.2007 16:14:47

Re: SQLite3

Сообщение Vadim » 16.07.2018 08:35:17

arriah
Попробуйте начать разработку БД с того, что на самом обычном русском языке, самым обычным текстом написать:
- какие данные должны храниться и, соответственно, обрабатываться;
- процедуры обработки данных. Начинаете с исходных данных и что в результате должно получиться.
Повторюсь - никакого программирования, SQL и прочей лабуды, всё обычным текстом. Хорошо бы с рисунками. Ни в коем случае не должно быть неоднозначности в интерпретации тех или иных данных.
Это называется - разработка бизнес-логики. После этого структура БД и приложения можно с лёгкостью перевести на что угодно. ;-)

Добавлено спустя 6 минут 14 секунд:
arriah писал(а):И как правильно в моем случае связывать машину с водителем или водителя с машиной?

В том коде, что Вы представили, содержаться так называемые справочные данные, т.е. это у Вас справочные таблицы, откуда берутся правильные данные. А вот рабочие таблицы, которые хранят суть работы с данными, у Вас полностью отсутствуют. Правильные связи, с отслеживанием актуальности данных, Вы будете устанавливать между справочными и рабочими таблицами. На текущий момент у Вас рабочие таблицы отсутствуют, следовательно, над спецификациями связей можно думать хоть до морковкиного заговения - всё равно ничего не получится. ;-)

Добавлено спустя 3 минуты 1 секунду:
Снег Север
Не пугайте ребёнка множественностью пользователей. Ему бы просто с БД разобраться... :-D
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: SQLite3

Сообщение arriah » 22.07.2018 16:08:02

Спасибо всем за ответы, очень помогли :)
Но вот столкнулся с другой проблемкой, кого винить я хз :)

Не могу понять, почему не вносятся изменения в базу данных при использовании DBGrid и DBNavigator?
Софтина работает только через SQLQuery.
Сделал отдельную форму для редактирование таблиц.
На форму закинул DataSource, TSqlite3DataSet, DBNavigator.
При открытии формы устанавливаются соответствующие свойства для DataSet.
В DBGrid.AutoEdit:=True
ReadOnly везде False
dgEditing тоже True;

Форма открывается, записи показываются, кнопки на навигаторе работают исправно, но засада в том, что изменения не сохраняются. Ни при удалении записи, ни при редактировании, ни при вставке, хотя галочку на навигаторе нажимаю :).

Решил проверить:
при открытии таблицы указал DataSet.Edit,
На событие OnClick кнопки повесил:
DataSet.Post;
DataSet.ApplyUpdate;
Внес изменения в базу, жму на кнопку и ловлю ошибку с сообщение что мол БД не находится ни в режиме редактирования, ни в режиме добавления...

Я что-то не так делаю или это такие глюки? Проверил бы на дельфях, но лениво скачивать и ставить.

по сути, вариант с навигатором должен работать, но почему то не работает.

И небольшой вопросик про DBGrid. Сейчас у меня примерно так:
Код: Выделить всё
  DBGrid1.Columns.Clear;
  DBGrid1.Columns.Add.FieldName:='DriversFIO';
  DBGrid1.Columns.Add.FieldName:='DriversLic';
  DBGrid1.Columns.Add.FieldName:='DriversCar';
  DBGrid1.Columns[0].Title.Caption:='ФИО';
  DBGrid1.Columns[1].Title.Caption:='Номер в/у';
  DBGrid1.Columns[2].Title.Caption:='Автомобиль';

Вобщем добавляю столбец в таблицу и даю ему осмысленное название.
А можно ли как-то добавить это в одну строчку типа:
Add.FieldName['DriversFIO'].Title.Caption:='ФИО';
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: SQLite3

Сообщение pupsik » 22.07.2018 23:18:45

Вроде со всем разобрался
....
Ни при удалении записи, ни при редактировании, ни при вставке, хотя галочку на навигаторе нажимаю
и т.п....

Есть вики. Там всё описано. Запросы надо добавить что бы работало.

БД должна состоять из трех таблиц
судя по описанию... из 4-х...
pupsik
энтузиаст
 
Сообщения: 1154
Зарегистрирован: 20.08.2014 16:20:13

Re: SQLite3

Сообщение Снег Север » 23.07.2018 08:58:07

С SQLite3Connection связать SQLTransaction и выставить у него caCommitRetaining. У SQLQuery в опциях поставить [sqoAutoApplyUpdates].
Вложения
sqlite_test.zip
тестовый пример
(128.62 КБ) Скачиваний: 597
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3039
Зарегистрирован: 27.11.2007 16:14:47

Re: SQLite3

Сообщение arriah » 23.07.2018 17:48:28

Снег Север писал(а):С SQLite3Connection связать SQLTransaction и выставить у него caCommitRetaining. У SQLQuery в опциях поставить [sqoAutoApplyUpdates].

А при чем SQLQuery?
У меня набор данных через SQLite3Dataset.
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: SQLite3

Сообщение Снег Север » 23.07.2018 19:00:25

arriah писал(а):У меня набор данных через SQLite3Dataset.
А я не знаю, что это. Знаю, что то, что в моем примере - работает идеально и не только в тесте. Не устраивает - разбирайтесь сами.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3039
Зарегистрирован: 27.11.2007 16:14:47

Re: SQLite3

Сообщение arriah » 23.07.2018 19:32:52

Снег Север писал(а):А я не знаю, что это. Знаю, что то, что в моем примере - работает идеально и не только в тесте

Да ну? Прям-таки идеально?
Это ваш пример, при удалении записи:
error.PNG
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: SQLite3

Сообщение Снег Север » 24.07.2018 08:19:06

Эта ошибка при удалении через навигатор возникает от того, что в таблице не назначен primary key. Назначьте его на поле id и всё заработает.
Но всегда лучше удалять записи самостоятельно, вызовом SQL.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3039
Зарегистрирован: 27.11.2007 16:14:47

Re: SQLite3

Сообщение arriah » 25.07.2018 17:25:02

Снег Север писал(а):Эта ошибка при удалении через навигатор возникает от того, что в таблице не назначен primary key. Назначьте его на поле id и всё заработает.
Но всегда лучше удалять записи самостоятельно, вызовом SQL.

Я понял из-за чего ошибка :) Это так, тролинг по поводу "идеальности". Ничего личного)
Проблем удаления через запросы SQL нет, но хотелось сделать без запросов, через DataSet,
Сделал пробный проект в дельфи - там работает. а в лазаре не хочет. Вобщем сделал через SQLQuery, чтобы не копаться в причинах, но природу ошибки хотелось бы познать.

Вот тут http://www.cyberforum.ru/delphi-database/thread1631920.html описана моя проблема, правда для дельфи. И там вопрос решился пересозданием всего с нуля.
Вобщем странное поведение...
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35

Re: SQLite3

Сообщение Снег Север » 25.07.2018 18:10:32

arriah, это был у меня досстаточно давний тестовый пример, в котором я проверял совсем другие вещи. Но в программах, которые я делаю по работе, я никогда не использую ни навигатор, ни редактирования в гридах, ни вставку/удаление по усмотрению датасетов. Слишком много проблем с этим выскакивает в неожиданных местах. Гриды - только для быстрого просмотра, вставки - через формы с контролами редактирования конкретных полей, все измения - только самостоятельно формируемыми SQL-ми. Немного более громоздко, зато полный конроль.
Аватара пользователя
Снег Север
долгожитель
 
Сообщения: 3039
Зарегистрирован: 27.11.2007 16:14:47

Re: SQLite3

Сообщение arriah » 26.07.2018 06:45:13

Снег Север писал(а):arriah, Гриды - только для быстрого просмотра, вставки - через формы с контролами редактирования конкретных полей, все измения - только самостоятельно формируемыми SQL-ми. Немного более громоздко, зато полный конроль.

Полностью согласен :)
arriah
новенький
 
Сообщения: 94
Зарегистрирован: 29.07.2015 16:42:35


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 3

Рейтинг@Mail.ru