Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2014.05.18;
Скачать: CL | DM;

Вниз

Запись данных сразу в несколько таблиц   Найти похожие ветки 

 
AnacRon ©   (2011-02-15 20:48) [0]

Доброго всем времени суток!
Уже устал бегать по всем закаулкам инета и документации и решил спросить.
Сам я не силен в программировании (чайник   ), но встала задача, которую необходимо решить.
дано: Object pascal (дргим не владею), mysql (postgresql, sqlite).
имеем: несколько таблиц, одна из которых главная и представляет из себя список (журнал событий и т.п.):
CREATE TABLE `first` (
   `id` INT(6) NOT NULL AUTO_INCREMENT,
   `num` INT(9) NULL DEFAULT NULL,
   `desc` VARCHAR(20) NULL DEFAULT NULL,
   `data` DATE NULL DEFAULT NULL,
   `comment` VARCHAR(150) NULL DEFAULT NULL,
   PRIMARY KEY (`id`),
   UNIQUE INDEX `num` (`num`)
)

и несколько таблиц такого характера (параметры привязанных к списку предыдущей таблицы):
CREATE TABLE `second` (
   `id` INT(6) NOT NULL AUTO_INCREMENT,
   `num` INT(9) NULL DEFAULT NULL,
   `cnt` INT(9) NULL DEFAULT NULL,
   `par1` VARCHAR(120) NULL DEFAULT NULL,
   `par2` DECIMAL(11,3) NOT NULL,
   `par3` INT(2) NULL DEFAULT NULL,
   PRIMARY KEY (`id`),
   UNIQUE INDEX `cnt` (`cnt`, `num`, `par1`)
)

в коде: классы для работы с этими данными. Первая таблица
 TSecond = class //таблица с параметрами
 private
   Fid  : integer;
   Fnum  : string;  // номер записи в журнале по которому происходит выборка строк с параметрами
                    // SELECT s.id, s.cnt, s.par1, s.par2, s.par3 FROM first f, second s WHERE s.num=f.num
   Fcnt  : string;
   Fpar1  : string;
   Fpar2  : double;
   Fpar3  : integer;
 public
   constructor Create; overload;
 published
   property id  : integer read Fid write Fid;
   property num  : string read Fnum write Fnum;
   property cnt  : string read Fcnt write Fcnt;
   property par1  : string read Fpar1 write Fnam1;
   property par2  : double read Fpar2 write Fpar2;
   property par3  : integer read Fpar3 write Fpar3;
 end;

 TFirst = class (TObject) // таблица списка (журнала)
 private
   Fnum  : string;
   Fdesc  : string;
   Fdata  : TDateTime;
   Fcomment  : string;
   FItems: TList;
   function GetItems(Row: integer): TSecond;
   procedure SetItems(Row: integer; const AValue: TSecond);
 public
   property Items[Row: integer]: TSecond read GetItems write SetItems;
   constructor Create; overload;
   destructor Destroy; override;
   function AddItem(item: TSecond): integer;
 published
   property num  : string read Fnum write Fnum;
   property dat  : TDateTime read Fdat write Fdat;
   property Tip  : boolean read FTip write FTip;
   property Itog  : double read FItog write FItog;
 end;

суть вопроса: Читаю все это по некоторым причинам не через на прямую в объект на конкретную запись журнала. Таких объектов может считаться сразу несколько с разных клиентских машин.
Данные из таблицы Second хранятся в TFirst.Items;
...
mySecond := TSecond.Create;
with SQLQuery of
try
 SQL.Text := "SELECT s.id, s.cnt, s.par1, s.par2, s.par3 FROM first f, second s WHERE s.num=f.num;";
 Open;
 mySecond.id := FieldByName("id").AsInteger;
 mySecond.cnt := FieldByName("cnt").AsString;
 mySecond.par1 := FieldByName("par1").AsString;
 mySecond.par2 := FieldByName("par2").AsString;
 mySecond.par3 := FieldByName("par3").AsString;
 Close;
except
end;
myFirst.AddItem(mySecond);
...

Затем возможны изменения в этом самом Items (вставка, редактирование, удаление). И ни как не могу придумать чтобы записать эти изменения в таблицу (вставка, редактирование, удаление) т.к. считанные и измененные объекты могут сохраняться в разные периоды и с разных машин.
Если вопрос совсем детский то прошу прощения. и пните в нужную сторону! уже несколько вариантов испробовал убил целую неделю но так и не разработал нужный алгоритм.


 
KilkennyCat ©   (2011-02-15 23:47) [1]


> (вставка, редактирование, удаление) т.к. считанные и измененные
> объекты могут сохраняться в разные периоды и с разных машин.
>

ты имеешь ввиду, как избежать ситуацию, типа: когда один клиент запись удалил, а второй ее изменил?


 
Гость   (2011-02-16 09:11) [2]


> Читаю все это по некоторым причинам не через на прямую в
> объект на конкретную запись журнала.

честно, не понял
>> все сообщения в форуме должны быть на русском языке

если суть в
>>как избежать ситуацию, типа: когда один клиент запись удалил, а второй ее изменил?

то можно сделать так:
Запись не удаляется, а в таблицах заводится поле IS_DELETED и ставит в true при удалении, соответственно такие записи не показываются потом. Но! их можно изменять. Только при update ставить проверку на поле IS_DELETED и предупреждать, что запись вообще-то удаленная.  А по логу, если ведется, а если нет - то вести, можно поднять кем и когда. И можно восстановить запись при выполнении update, если права юзера и бизнес-правила позволяют.


 
MsGuns ©   (2011-02-16 10:43) [3]

>Гость   (16.02.11 09:11) [2]

Не надо советовать ерунду


 
Гость   (2011-02-16 10:55) [4]

MsGuns ©   (16.02.11 10:43) [3]
что именно?

и осталось сказать более чем 5ти разработчикам известных в России программ, с коими доводилось работать, в т.ч. http://www.sbscorp.ru/ и http://www.servplus.ru/branches/tradeauto/supermag/supermag_step_by_step/
что они делают по ерундовым принципам


 
MsGuns ©   (2011-02-16 12:41) [5]

>Гость   (16.02.11 10:55) [4]
>что именно?

Попытки "заведения" специальных полей, где должны отмечаться блокировки записей. Бо это неминуемо заведет в могилу.
Делать это (предотвращать коллизии между пользователями, например, используя механизи блокировок) нужно исключительно средствами СУБД, а если таковых не имеется (не знаю постгрес), то соответственно продумывать интерфейс (с помощью трехзвенки например)

На этом ресурсе туча конференций на эту тему


 
MsGuns ©   (2011-02-16 12:47) [6]

И еще мертвичина - это "условно" удаленные записи. Превносит путаницу и неразбериху в работе юзверей и перманентую головную боль администратору БД.
Восстановление "убитых" записей борется штатными средствами:
- тактическими через рестор базы
- стратегически через порку виновного розгами с последующим заставлением оного повторно ввести документ. Через некоторое время товарысч перейдет на работу по принципу "7 раз проверь - один раз удали"


 
MsGuns ©   (2011-02-16 12:52) [7]

И последнее
Ежели программа построена по принципу "записей", то в топку такую программу не смотря на красивые рюшечки и окошечки. Нормальные "взрослые" программы оперируют объектами: документами, операциями, ТМЦ, проводками и т.д. "Просто так" объекты не удаляют, для этого должно быть основание - это раз. Все удаления (итзменения, вставки) автоматически должны заноситься в логи, кои и просматриваются в случае "разбора полетов"

Придумывать велосипеды с шестеренчатыми колесами и тремя рулями может и интересно кому-то, но неблагодарно. Как минимум


 
Гость   (2011-02-16 13:02) [8]

2 MsGuns ©

Гость   (16.02.11 10:55) [4] было к чему:
К тому, что сделать как с технологией 1с, документ проведен или непроведен. (влияет или нет на остатки). Не тот же ли это признак удален или не удален, только с иной точки зрения?

>> "условно" удаленные записи. Превносит путаницу и неразбериху в работе юзверей и перманентую головную боль администратору БД.
это да. это согласен. и программировать намного сложнее. но ведь и гибче

>> туча конференций на эту тему
да-да, и на других тоже много

"условно" удаленные записи все равно нужны,
ну можно назвать иначе, как архив, корзина ну и прочие слова. Только суть все равно не меняется. В многоссылочной БД порой невозможно удалить без ТАКОГО каскадного удаления, что при малейшей ошибке потом не соберешь концы


 
clickmaker ©   (2011-02-16 13:19) [9]

> В многоссылочной БД порой невозможно удалить без ТАКОГО
> каскадного удаления

логику надо не на каскадных триггерах строить, а выносить в хранимки, например. А иначе и правда концов не найдешь


> "условно" удаленные записи все равно нужны

для архивов лучше отдельные таблицы заводить


 
Anatoly Podgoretsky ©   (2011-02-16 13:41) [10]

> Гость  (16.02.2011 13:02:08)  [8]

1С это пример как не надо делать.


 
Гость   (2011-02-16 14:20) [11]

2 Anatoly Podgoretsky ©   (16.02.11 13:41) [10]
сам не люблю :-|)
а все сидят в ней. Как, извинения прошу, презерватив. Никто не любит, а все юзают

2 clickmaker ©   (16.02.11 13:19) [9]
>>логику надо не на каскадных триггерах строить, а выносить в хранимки, например. А иначе и правда концов не найдешь
не всегда получается.
потом как вспомнят что-то.. ну и выбор: или 80% переписывать или триггер.

>>для архивов лучше отдельные таблицы заводить
чем лучше?
партицирование (или ключ) навесить на признак deleted и нормально


 
clickmaker ©   (2011-02-16 14:56) [12]

> >>для архивов лучше отдельные таблицы заводить
> чем лучше?

тем что отдельно и не надо "партицирование (или ключ) навесить на признак deleted".
поиск по архиву, как правило, в разы, а то и на порядок реже, чем по живым таблицам. Нафига баласт на борту держать?


 
MsGuns ©   (2011-02-16 16:13) [13]

>clickmaker ©  

Он (Гость), как кот Васька, читает, но делает по своему.
Его вряд ли переубедить :)


 
AnacRon ©   (2011-02-16 21:36) [14]

Всех благодарю за мнения!

> сам не люблю :-|)
> а все сидят в ней. Как, извинения прошу, презерватив. Никто
> не любит, а все юзают

вопрос рекламы. и не образованности пользователя.


 
DiamondShark ©   (2011-02-17 10:58) [15]


> MsGuns ©   (16.02.11 12:41) [5]
> MsGuns ©   (16.02.11 12:47) [6]
> MsGuns ©   (16.02.11 12:52) [7]


"Не надо советовать ерунду" (Ц)


 
MsGuns ©   (2011-02-17 15:51) [16]

>DiamondShark ©   (17.02.11 10:58) [15]

Посмеялсо. Пасибки


 
DiamondShark ©   (2011-02-17 18:08) [17]


> MsGuns ©   (17.02.11 15:51) [16]

Давай посмеёмся вместе.

[5]
Есть простейшая база данных из одной таблицы:
CREATE TABLE Entity(
ID int not null identity(1,1) primary key,
Name varchar(256) not null
)

С тебя два примера приложения для просмотра, ввода и модификации этой информации с предотвращением коллизий.
Первый -- средствами СУБД
Второй -- продуманным интерфейсом (с помощью трехзвенки например)

[6]

В предыдущий пример вносится небольшое расширение.

CREATE TABLE EntityFacts(
ID int not null identity(1,1) primary key,
Entity int not null,
FactDate datetime not null,
FactInfo TFactInfo not null,
CONSTRAINT FK_Entity FOREIGN KEY(Entity) REFERENCING Entity(ID)
)

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

С тебя:
- пример приложения без коллизий и без каких либо дополнительных флагов.
- инструкция для оператора центральной базы с чёткими указаниями, какие записи из Entity он не имеет права удалять или модифицировать.

[7]

С тебя версии приложений из предыдущих пунктов, только с объектами, без каких-либо манипуляций с записями.



Страницы: 1 вся ветка

Текущий архив: 2014.05.18;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.007 c
2-1375088425
Вова
2013-07-29 13:00
2014.05.18
Помогите перевести с Java на Delphi


6-1272272116
Дмитрий Белькевич
2010-04-26 12:55
2014.05.18
Indy 10 обновляется?


15-1384191766
awt
2013-11-11 21:42
2014.05.18
Проблема с изучением ассемблера...


15-1383152239
Rouse_
2013-10-30 20:57
2014.05.18
Требуется небольшая вычитка статьи.


2-1374915886
blackmane
2013-07-27 13:04
2014.05.18
Вывод формы в активный сеанс