Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2014.05.18;
Скачать: [xml.tar.bz2];

Вниз

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

 
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;
Скачать: [xml.tar.bz2];

Наверх





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


2-1375017722
SkAndriy
2013-07-28 17:22
2014.05.18
Delphi XE4 функция StrPCopy не рекомендована


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


2-1375013572
SkAndriy
2013-07-28 16:12
2014.05.18
Delphi XE как скомпилировать свой компонент под Win 64 bit?


15-1381867348
Германн
2013-10-16 00:02
2014.05.18
Линукс





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский