Как организовать таблицу и индексы

Shamik
Дата: 17.02.2010 21:01:55
Есть таблица хранящая активы клиентов, их количество на счетах, цену и стоимость актива на счете, а также сабтоталы (по счетам на каждую дату) и тотал по клиенту на дату.

CREATE TABLE T1(
[Client] [int] NOT NULL, - ид клиента
[Date] [datetime] NOT NULL, - дата
[Account] [int] NULL, - счет
[Active] [int] NULL, - ид актива на счете (от 1 до 100 на каждом счете)
[Value] [numeric](18, 6) NULL, - кол-во единиц актива
[Price] [numeric](18, 6) NULL, - цена на дату
[Summ] [numeric](18, 2) NOT NULL, - сумма
[SummType] [tinyint] NOT NULL - тип суммы (актив, сабтотал, тотал)
) ON [PRIMARY]
GO

Кол-во записей будет около 200-300 млн и будет добавляться минимум по 300тыс в день. Скорость вставки имеет меньшее значение чем выборки но имеет. Обновлений не будет. Выборки будут select ... where Date between (...) and Account(Client)=... and SummType=...

Как лучше организовать структуру и данные? Будет ли жить такая табл в sql 2008 или разбивать на N таблиц по датам или ид клиента? Пока принял решение создать один кластерный индекс (Client, Date, Account, SummType) и все. Смущает то что он будет не уникальным. Может лучше создать синтетический ПК и потом уже индекс по нужным полям?

ЗЫ:

Еще один вариант в голову приходит - создать две таблицы, в одной состояния счетов (ид состояний) в другой собственно детализация состояний по активам

Client
Date
Account
SummType
StateID

StateID
Active
Value
Price
Summ

и выбирать нужные данные двумя запросами (без джойнов).
iap
Дата: 17.02.2010 21:48:26
В структуру не вникал, но если в [Date] не хранится ненулевое время, то лучше тип DATE.

Кстати, неудачное название поля - совпадает с ключевым словом (названием типа данных).

Вообще-то, здесь на сайте есть специальный форум по проектированию БД...
Shamik
Дата: 17.02.2010 23:16:18
В Date время нулевое... кстати сервер 2005, если апнуть до 2008 и использовать тип Date - выиграем ли в размере и скорости поиска по индексу? Date ведь меньше чем datetime. Но в ближайшее время там будет 2005, обновление пока не запланировано да и времени потребует а задача горит.

Таблицу я решил разбивать по ид клиентов: 1 - N в одной табл, N+1 - M в другой итп.
Надо понять что делать с индексами - все рьяно советуют иметь уникальный кластерный индекс, без этого никак итп...сделать ли синтетический или оставить как есть?
AHDP
Дата: 18.02.2010 07:50:25
А оборудование позволит эфективно использовать "секционированную" таблицу?
Я бы разбил таблицу на три:
1) активы клиента;
2) сабтоталы (не уверен, что если субтоталы меняются не регулярно, то их стоит хранить именно на каждый день);
3) тоталы по клиенту.
Минимум от одного условия в where сразу избавитесь и суммарный размер данных уменьшится.

ЗЫ По вашим оценкам получается, что таблица(ы) будет(ут) подрезаться не реже чем раз в три года? Так может тогда сразу её(их) по периодам побить?
iap
Дата: 18.02.2010 09:26:00
Shamik
В Date время нулевое... кстати сервер 2005

А это кто писал?
Shamik
Будет ли жить такая табл в sql 2008 или разбивать на N таблиц по датам или ид клиента?
Shamik
Дата: 18.02.2010 12:29:02
AHDP,

Данные меняться не будут (история).
А какие требования к оборудованию должны быть?

iap,
сори ошибся 2005-й у нас (9.0..)
Shamik
Дата: 18.02.2010 12:33:37
AHDP,

Подрезаться табл не будут, просто первоначально надо загрузить столько а потом объемы будут только расти. По датам бить не очень хорошо, лучше по клиентам. Потому что запросы будут по конкретному клиенту или счету, но за любой период. Страшных union all плодить не хочется.
AHDP
Дата: 18.02.2010 14:42:34
Количество дисков, процессоров... Какой смысл дробить таблицу, если в результате все её части будут лежать на одном диске?
У Вас будет постоянный список клиентов? Администрировать такое решение будет сложнее.
Можно уточнить требования к запросам за произвольный период в части требований к остаткам на дату и отображению операций в нём?
ЗЫ Интересно узнать как Вы собираетесь вытаскивать одним запросом из вашей таблицы первоначальный баланс, обороты и конечный баланс.
Shamik
Дата: 18.02.2010 15:29:42
AHDP,
Смысл очень простой - выполнять запрос по таблице содержащей меньше записей ))
Тупо if a<N select from TableN else if a<M select from TableM.

Процессоров 4, диск будем считать что один (на самом деле массив но распределением я управлять не могу). Список клиентов будет расти. В табл будут только остатки на каждую дату, обороты для данной задачи не нужны.
AHDP
Дата: 18.02.2010 16:06:16
Стоит ли овечка выделки?

Если не нужны "обороты", то тогда зачем эти поля?
[Active] [int] NULL, - ид актива на счете (от 1 до 100 на каждом счете)
[Value] [numeric](18, 6) NULL, - кол-во единиц актива
[Price] [numeric](18, 6) NULL, - цена на дату

ЗЫ Я не уверен в том, что у вас таблица будет равномерно заполнена полезными данными:(