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

Вниз

Как правильно организовать частые добавления в БД   Найти похожие ветки 

 
Ярослав   (2005-10-03 12:56) [0]

Ситуация такая - С устроойства через com port поступают данный, порядка 5 - 20 записей в секунду, мне все их нужно записать в БД, данные на экране пользователя должны обновляться 1 раз в секунду, как лучше добавлять  данные в БД
Каждую запись отдельно с подтверждением транзакции или к примеру пакетами 1 раз в секунду и подтверждать транцакцию для всего пакета, а не для каждой отдельной записи?


 
Sergey13 ©   (2005-10-03 13:02) [1]

Я бы для начала разделил задачу на две (независимые).
1. Добавление.
2. Показ юзеру.

>данные на экране пользователя должны обновляться 1 раз в секунду
Глазки у него не заболят? 8-)


 
Desdechado ©   (2005-10-03 13:02) [2]

если тебя не интересует каждая конкретная запись сразу после вписывания ее в БД, то лучше пакетами - это быстрее


 
Курдль ©   (2005-10-03 13:14) [3]


> Ярослав   (03.10.05 12:56)
> Каждую запись отдельно с подтверждением транзакции или к
> примеру пакетами 1 раз в секунду и подтверждать транцакцию
> для всего пакета, а не для каждой отдельной записи?


Меня всегда развлекало манипулирование термином "транзакция". Такое впечатление, что программист пытается прибавить себе значимости звучным словом :)

Чаще всего компоненты доступа сами разбираются с транзакциями на низшем уровне. Думаю, что "IB..." делают так же. Если Вам не надо отслеживать пакеты взаимосвязанных записей разных таблиц (которые либо все должны попасть в БД, либо все отмениться), - забудьте про транзакции! Работайте простыми DML!


 
Desdechado ©   (2005-10-03 13:47) [4]

> забудьте про транзакции
вредный совет

понимать механизм транзакций и грамотно применять его - важно
кто считает иначе - неуч без возможности лечения


 
Курдль ©   (2005-10-03 13:51) [5]


> Desdechado ©   (03.10.05 13:47) [4]
> понимать механизм транзакций и грамотно применять его -
> важно
> кто считает иначе - неуч без возможности лечения


Однозначно согласен! Пихать транзакции куда ни попадя - это и есть неграмотное их применение!

Вот Вы, как вижу, неправильно понимаете механизм транзакций.
Например то свойство СУБД, что они сами открывают, закрывают (или откатывают транзакции в случае ошибки) по умолчанию при любом активном DML (не select).


 
Desdechado ©   (2005-10-03 14:00) [6]

> свойство СУБД - они сами закрывают транзакции по умолчанию
чушь

закрытие требует явной команды commit или rollback (rollback может быть неявным - при ошибке, НП)

компоненты могут сами ее делать, но это нельзя назвать грамотным применением
Запись пачками - это и есть ЯВНОЕ указание транзакций, ибо по умолчанию "одна операция - одна транзакция" (по крайней мере, в БДЕ). В IBExpress - там вообще любую транзакцию надо явно указывать. Имхо, авторы компонентов перегнули палку, но все-таки в правильную сторону.


 
Курдль ©   (2005-10-03 14:24) [7]


> Desdechado ©   (03.10.05 14:00) [6]
>
> > свойство СУБД - они сами закрывают транзакции по умолчанию
> чушь
>
> закрытие требует явной команды commit или rollback (rollback
> может быть неявным - при ошибке, НП)
>


Вы бы заявляли не так категорично! А то ж обидно, что "чушь"! :)

Повторяю: "УВАЖАЮЩИЕ СЕБЯ СУБД, И ИНТЭРБЭЙС В ТОМ ЧИСЛЕ, ОТРАБАТЫВАЮТ ТРАНЗАКЦИОННЫЙ ПРОЦЕСС БЕЗ ВНЕШНЕГО ВМЕШАТЕЛЬСТВА"!

Закрытие транзакции и вправду требует явного указания, но в случае, если транзакция была ЯВНО ОТКРЫТА!

Думаю, что компоненты IB, как наследники от TDataSet и TDataBase вполне исполнят такой код:

DataBase.ApplyUpdates([DataSetMaster, DataSetSlave1, DataSetSlave2...]);

При этом транзакция автоматически откроется, данные занесутся в бд и транзакция закроется, либо откатится.


 
ANB ©   (2005-10-03 14:37) [8]

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

По сабжу : сделать буфферизацию и получение / складывание в базу строк развести асинхронно (можно в разных потоках).


 
Ярослав   (2005-10-03 14:43) [9]

> Курдль ©   (03.10.05 13:14) [3]
> Чаще всего компоненты доступа сами разбираются с транзакциями на низшем уровне. Думаю, что "IB..." делают так же.

В IB управление транзакциями возможно только на клиенте
В компонентах можно настроить чтобы транзакция подтвердалась после добавления каждой записи, а можно и управлять ими вручную

> Меня всегда развлекало манипулирование термином "транзакция". Такое впечатление, что программист пытается прибавить себе значимости звучным словом :)
:)) Для кого звучное слово, а кто этим постоянно пользуестя :)


 
Курдль ©   (2005-10-03 14:52) [10]


> :)) Для кого звучное слово, а кто этим постоянно пользуестя


Не обижайтесь, возможно я вспылил по отношению к Вам! Переходите на более сложные инструменты - тоже забудете о таких мелочах! :)


 
ANB ©   (2005-10-03 14:55) [11]


> Ярослав   (03.10.05 14:43) [9]


> Курдль ©   (03.10.05 14:52) [10]

Автор не просил холивара, он просил совета.
ЗЫ. Я с ИБ/ФБ не работаю, посему толком посоветовать ничего не могу.


 
Курдль ©   (2005-10-03 15:02) [12]

Ок! Вопрос к автору, который поможет вникнуть в проблему.
Данные поступают от устройства непрерывно, или когда-то останавливаются?
Если целыми днями непрерывно - есть смысл писать непрерывно. Я работал с ИБ, но не при помощи компонентов IB..., а с SQLDirect через ODBC.  Помню, что тестовая программа для контроля производительности писала строки в IB сотнями, а то и тысячами в секунду.
Если других пользователей не будет - я думаю и проблем не будет.


 
Ярослав   (2005-10-03 15:13) [13]

Данные от устройства поступают непрерывно и целыми днями, и 5 - 20 записей в секунду это текущая нагрузка, она может увеличиться до сотни записей в секунду, вот я и думаю как это сделать, писать каждую запись отдельно... или какими нибудь пакетами
Другие пользователи могут только читать эти записи, не добовлять не редактировать их не могут, да и пользователей немного 2-3 максимум 10


 
Ярослав   (2005-10-03 15:13) [14]

Данные от устройства поступают непрерывно и целыми днями, и 5 - 20 записей в секунду это текущая нагрузка, она может увеличиться до сотни записей в секунду, вот я и думаю как это сделать, писать каждую запись отдельно... или какими нибудь пакетами
Другие пользователи могут только читать эти записи, не добовлять не редактировать их не могут, да и пользователей немного 2-3 максимум 10


 
Курдль ©   (2005-10-03 15:19) [15]


> Ярослав   (03.10.05 15:13) [14]
> Данные от устройства поступают непрерывно и целыми днями,
>  и 5 - 20 записей в секунду это текущая нагрузка, она может
> увеличиться до сотни записей в секунду, вот я и думаю как
> это сделать, писать каждую запись отдельно... или какими
> нибудь пакетами
> Другие пользователи могут только читать эти записи, не добовлять
> не редактировать их не могут, да и пользователей немного
> 2-3 максимум 10


ОК! Понятно, что разбиение на пакеты скорости не добавит.
Рекомендую сделать лабораторную работу - простенькую программу, записывающую данные в БД, по объему равные рабочим. Откатать ее на предполагаемой конфигурации, а потом уже принимать решение - либо принять, как есть, либо искать компромиссы (ограничивать скорость, ....
==========================================================

Я вот тут писал все это и вдруг решил посчитать 100 х 3600 х 24 - это ж 8 640 000 записей в сутки!!!!!!!   Какой тут IB/FB??!!!!


 
ANB ©   (2005-10-03 15:22) [16]


> писать каждую запись отдельно... или какими нибудь пакетами
- критичность потери записей ?


 
Desdechado ©   (2005-10-03 15:26) [17]

> Вы бы заявляли не так категорично! А то ж обидно, что "чушь"
Если некие средства доступа к БД скрывают функциональность сервера, то это проблема этих средств и их пользователей. Еще раз повторю: за программиста никто не выдаст команды подтверждения транзакции. Разве только особо "интеллектуальные" средства доступа, "угадывающие" желания программиста (по сути - расслабляющие и сбивающие с толку).


 
ANB ©   (2005-10-03 15:33) [18]


> Я вот тут писал все это и вдруг решил посчитать 100 х 3600
> х 24 - это ж 8 640 000 записей в сутки!!!!!!!   Какой тут
> IB/FB??!!!!
 - точно, точно, пусть переходит на оракл !.
ЗЫ. А куда столько инфы класть то ? Этож сколько места под все это надо ?


 
Курдль ©   (2005-10-03 15:42) [19]


> Desdechado ©   (03.10.05 15:26) [17]
>  Еще раз повторю: за программиста никто не выдаст команды
> подтверждения транзакции. Разве только особо "интеллектуальные"
> средства доступа, "угадывающие" желания программиста (по
> сути - расслабляющие и сбивающие с толку).

До чего ж Вы упрямы! Если программист не открыл транзакцию насильственно (методами компонента доступа, либо соответствующим DML типа
BEGIN TRAN[SACTION] [ transaction-name ]
то ее и закрывать не надо!!! Напр, если написать
insert into TABLE_NAME (FIELD_NAME) value (1)
то транзакция откроется, закроется или откатится автоматически под управлением СУБД.


> ANB ©   (03.10.05 15:33) [18]
>  - точно, точно, пусть переходит на оракл !.
> ЗЫ. А куда столько инфы класть то ? Этож сколько места под
> все это надо ?

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


 
Desdechado ©   (2005-10-03 15:56) [20]

> то ее и закрывать не надо
открыться-то откроется (на большинстве СУБД), то вот закрыться она сама не пожелает, ибо это противоречит азбуке СУБД
если кто-то считает, что это не так, то он уже успел почуствовать на себе тлетворное влияние "интеллектуальных" компонентов

далнейший диспут считаю бессмысленным.

Кстати, 8 млн записей в сутки - не такое уж и большое кол-во для FB. Да и размер записи важен тоже. И автор ничего не говорил о времени их хранения. Может, накопление и анализ идет понедельный, а более древнее агрегируется и списывается...


 
Курдль ©   (2005-10-03 16:07) [21]


> Desdechado ©   (03.10.05 15:56) [20]
> если кто-то считает, что это не так, то он уже успел почуствовать
> на себе тлетворное влияние "интеллектуальных" компонентов
> далнейший диспут считаю бессмысленным.


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


 
Evegny V   (2005-10-03 16:08) [22]

Курдль ©  >Если программист не открыл транзакцию насильственно ,то транзакция откроется, закроется или откатится автоматически под управлением СУБД.

Когда это произойдет для FB1.5?

Для IB скажем 6,5 (c 7 не работал не знаю) и FB1.5 нормальным считается:

-транзакцию надо стартовать для каждого запроса, включая select, клиентом;
- транзакция закрывается клиентом, включая select;

Я не рассматриваю случаи, когда на себя это берут компоненты.

Насколько я читал, есть две модели работы с транзакциями, явного старта - это IB и клоны, есть и дргие субд, но не помню точно, какие. И вторая модель, это авто старта транзакции - это например оракл.  А вот автозакрытие?? Возможно  какие-то субд поддерживают, но не помню или не знаю. Закрытие по тайм-ауту или дисконнекту не рассматриваю в контексте данного вопроса.


 
Sergey13 ©   (2005-10-03 16:15) [23]

2[21] Курдль ©   (03.10.05 16:07)
>Уверяю, что никакого открытия или закрытия транзакции не потребуется, чтобы измененные данные утвердились в БД.

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


 
Андрей Жук ©   (2005-10-03 16:20) [24]


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

- Чем докажешь?
- Мамой клянусь!

Запускаем SQLPlus.
Создаем таблицу
SQL> create table aaa
 2  (a int);

Table created.


Делаем выборку
SQL> select * from aaa;

no rows selected

Открываем второй екземпляр SQLPlus.
Добавляем запись
SQL> insert into aaa values (2);

1 row created.

Делаем выборку в первом экземпляре
SQL> select * from aaa;

no rows selected

Делаем выборку во втором экземпляре
SQL> select * from aaa;

        A
----------
        2

Закрываем 1 и 2 экземпляр.
Запускаем заново. Делаем выборку
SQL> select * from aaa;

no rows selected


Делаем вывод. Тов. Курдль - вы с умным видом несете ахинею.


 
Курдль ©   (2005-10-03 16:22) [25]


> Evegny V   (03.10.05 16:08) [22]
> -транзакцию надо стартовать для каждого запроса, включая
> select, клиентом;
> - транзакция закрывается клиентом, включая select;


Транзакция для select обусловлена замысловатой "антиблокировочной" системой IB. Это совсем не плохо, но не говорит об обязательности открытия и закрытия транзакций! Это лишь позволит избежать блокировок при перекрестном доступе.


 
Evgeny V ©   (2005-10-03 16:24) [26]

Приношу извинения, за неправильное написание ника в посте 22. Пост 22 мой:-)


 
Курдль ©   (2005-10-03 16:29) [27]


> Андрей Жук ©   (03.10.05 16:20) [24]
> insert into aaa values (2);


А если так:

insert into aaa values (2)
/

?


 
Андрей Жук ©   (2005-10-03 16:39) [28]

Естественно, разницы нет.
Пока не будет сделан COMMIT данные в не будут "закреплены".
Есть СУБД, в которых можно читать данные из неподтвержденных транзакций. Это, имхо, изврат.


 
ANB ©   (2005-10-03 16:41) [29]


> Курдль ©   (03.10.05 16:07) [21]
- для оракла - пример ошибочный. Пока явно коммит не укажешь - ничего не запишется. А транзакция стартует в нем автоматически. Другое дело, если работаешь с компонентами доступа. Почти все (а других и не знаю), по умолчанию выдают коммит после каждого DML. Этот режим можно либо отключить, либо явно начинать транзакцию (начало транзакции на оракл не передается, ибо для него это бессмысленно).

Другое дело - MS SQL. Там даже в T-SQL предусмотрены команды явного начала транзакции. В противном случае - работает автокоммит. Можно ли его выключить - я не разбирался, так же не знаю, можно ли в мс скл коммитить без явного старта транзакции.

> Андрей Жук ©   (03.10.05 16:20) [24]

Если начнем переходить на личности, то ветку прикроют, а вам р/о опять влепят.


 
ANB ©   (2005-10-03 16:42) [30]


> Андрей Жук ©   (03.10.05 16:39) [28]
- это еще надо соответствующий уровень изоляции поставить.


 
Sergey13 ©   (2005-10-03 16:45) [31]

2[29] ANB ©   (03.10.05 16:41)
>Пока явно коммит не укажешь - ничего не запишется.
Достаточно и не явного. 8-)


 
ANB ©   (2005-10-03 16:47) [32]


> Sergey13 ©   (03.10.05 16:45) [31]
- а как в sql plus сделать неявный коммит ?


 
Sergey13 ©   (2005-10-03 16:52) [33]

2[32] ANB ©   (03.10.05 16:47)
Любой DDL запрос или (у меня вроде так) закрытие программы (сессии). Еще вроде комманды управления системой типа Alter Session.


 
Курдль ©   (2005-10-03 16:53) [34]

ПОСЫПАЛ ГОЛОВУ ПЕПЛОМ!!! :)
И вправду я затуманен компонентами доступа с автокоммитом!
Транзакция ОТКРЫВАЕТСЯ автоматом при активном DML!

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


 
ANB ©   (2005-10-03 17:44) [35]


> Курдль ©   (03.10.05 16:53) [34]
- не то, чтобы очень напрягает, наоборот, коммит каждые, например, 1000 записей дает даже небольшой выигрыш по времени, но выигрыш довольно мал, а граблей довольно много. В общем ты в основе - прав. Если транзакции особо не нужны, нет смысла упрямо пытаться везде, где только можно их впихнуть. Исключение - случай, когда они действительно нужны.

ЗЫ. А таки работа с транзакциями в оракле мне больше всего нравится.


 
Андрей Жук ©   (2005-10-03 18:20) [36]


> ЗЫ. А таки работа с транзакциями в оракле мне больше
> всего нравится.

Особенно невозможность сделать COMMIT в теле процедуры...


 
jack128 ©   (2005-10-03 20:16) [37]

ANB ©   (03.10.05 17:44) [35]
но выигрыш довольно мал, а граблей довольно много.

какие грабли могут быть в
IBTransaction.StartTransaction;
try
 for i := 0 to Buffer.Count - 1 do
 begin
   SetSQLParams(IBSQL, Buffer[i]);
   IBSQL.ExecQuery;
 end;
finally
 IBTransaction.Commit;
end;

?


 
Sergey13 ©   (2005-10-04 10:01) [38]

2[36] Андрей Жук ©   (03.10.05 18:20)
А чем это сильно плохо?


 
Виталий Панасенко   (2005-10-04 10:17) [39]

Ссылаюсь на Ч.Калверта - "замечено, что применение кешированных изменений увеличивает производительность".. В принципе, нет никакого отличия от пакетного варианта..Я о возможной потери данных.. Так как и в пакетном варианте до подтверждения транзакции все равно ничего не "поимеем", и в этом в случае падения клиента.... Я просто думаю, сможет ли клиент "успеть" за поступающими данными при работе с IB?..Успеет ли он(клиент) затолкать запись в таблицу до поступления новых данных... особенно, при интенсивном поступлении данных и уже приличных накопленных данных.. На счет дискового пространства (1) и размера БД(2) - можно диск приличный воткнуть(1) и создать многофайловую БД (2)... Теоретически для IB было 131 тБ для 8к страницы, если мне память не изменяет..


 
Desdechado ©   (2005-10-04 10:36) [40]

> ПОСЫПАЛ ГОЛОВУ ПЕПЛОМ
Хорошо, хоть хватило мужества признать свою ошибку :)

> Тем более, что открытая транзакция напрягает сервер БД.
Тебе ее все равно открывать нужно, причем если на каждую запись своя транзакция, то открывать их нужно много, что больше напрягает сервер, чем 1 транзакция в секунду на 5-100 записей.



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

Форум: "Базы";
Текущий архив: 2005.11.13;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.044 c
9-1120030753
Зм1й
2005-06-29 11:39
2005.11.13
Морфинг


11-1109269615
rofl
2005-02-24 21:26
2005.11.13
KOLMediaPlayer SendCommand


14-1130153575
bSava
2005-10-24 15:32
2005.11.13
А что собственно с поиском по сайту?


6-1122714955
CAMCOH
2005-07-30 13:15
2005.11.13
Помогите плз с переходом Indy 9 - Indy 10


10-1106831444
Inco
2005-01-27 16:10
2005.11.13
Maссивы в IDL





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский