У меня есть около 1 миллиарда наборов данных, имеющих DatasetKey, и каждый из них содержит от 1 до 50 000 000 дочерних записей (некоторые объекты), в среднем это около 100, но есть много жирных хвостов.
Как только данныезаписано, обновление данных не производится, только чтение.
Мне нужно прочитать данные по DatasetKey и одно из следующего:
Получить количество дочерних записей
Получить первые 1000 дочерних записей(не более 1000)
Получить первые 5000 дочерних записей (не более 5000)
Получить первые 100000 дочерних записей (не более 100000)
Получить все дочерние записи
Каждая дочерняя запись имеет размер около 20 байт до 2 КБ (в среднем 450 байт).
Мой макет, который я хочу использовать, будет следующим:
Я создаю файл размером вне менее 5 МБ.
Каждый файл содержит как минимум один ключ DatasetKey, но если размер файла все еще меньше 5 МБ, я добавляю новые ключи DatasetKeys (с дочерними записями) до тех пор, пока не превышаю 5 МБ.какой файл-смещениеs Я найду, какие данные.
Далее я планирую хранить сериализованные пакеты с использованием буферов протокола.
Один пакет для первых 1000 записей,
один для следующих 4000 записей,
один дляследующие 95000 записей,
один для следующих оставшихся записей.
Я храню размеры файлов в ОЗУ (при сохранении всех заголовков требуется много ОЗУ, необходимого на машине, которую я использую).Когда мне нужно получить доступ к определенному ключу Dataset, я смотрю в оперативной памяти, какой файл мне нужен.Затем я получаю размер файла из оперативной памяти.Когда размер файла составляет около 5 МБ или меньше, я буду читать весь файл в память и обрабатывать его.Если это больше, чем 5 МБ, я буду читать только первый xKB, чтобы получить заголовок.Затем я загружаю нужную позицию с диска.
Как это звучит?Это полная чушь?Или хороший путь?
Используя этот дизайн, я имел в виду следующее:
Я хочу хранить свои данные в собственном двоичном файле, а не в базе данных, чтобы упростить резервное копирование иобрабатывать файлы в будущем.
Я бы использовал postgresql, но я решил, что хранение двоичных данных заставит postgresqls-toast выполнить более одного обращения к данным.
Хранение одного файла для каждого DatasetKey требует слишком много временидля записи всех значений на диск.
Данные рассчитываются в ОЗУ (поскольку не все данные помещаются одновременно в ОЗУ, они рассчитываются по блокам).
Размер файла 5 МБ - только приблизительная оценка.
Что ты скажешь?Заранее благодарю за помощь!
edit
Дополнительная справочная информация:
DatasetKey имеет тип ulong.
Дочерняя запись (есть разные типы) в большинстве случаев выглядит следующим образом:
public struct ChildDataSet
{
public string Val1;
public string Val2;
public byte Val3;
public long Val4;
}
Я не могу сказать, к каким именно данным обращаются.Планируется, что пользователи получат доступ к первым 1000, 5000, 100000 или всем данным определенных DatasetKeys.Исходя из их настроек.
Я хочу сохранить как можно меньшее время отклика и использовать как можно меньше дискового пространства.
@ Что касается произвольного доступа (вопрос Марка Гравелса):
Мне не нужен доступ к элементу №.123456 для конкретного ключа данных.
При хранении более одного DatasetKey (с дочерними записями) в одном файле (так, как я его разработал, чтобы не создавать много файлов), мне необходим произвольный доступ к первым 1000 записям определенного DatasetKey.в этом файле или в первых 5000 (так что я прочитал бы пакет 1000 и 4000).
Мне нужен только доступ к следующему, касающемуся одного конкретного DatasetKey (uint):
1000 дочерних записей (иливсе дочерние записи, если меньше 1000)
5000 дочерних записей (или все дочерние записи, если меньше 5000)
100000 дочерних записей (или все дочерние записи, если меньше 100000)
все дочерние записи
Все остальные вещи, о которых я упоминал, когда у меня пробовал только дизайн: -)
РЕДАКТИРОВАТЬ, потоковая передача для одного списка в классе?
public class ChildDataSet
{
[ProtoMember(1)]
public List<Class1> Val1;
[ProtoMember(2)]
public List<Class2> Val2;
[ProtoMember(3)]
public List<Class3> Val3;
}
Можно ли выполнить потоковую передачу для Val1, например, получить первые 5000 записей Val1