Похоже идея с вики действительно более привлекательна
на первоначальном этапе. Технологии особо не волнуют - знай
закатывай в асфальт тексты.
Просьба в связи с этим есть
- максимально выделять все что можно выделить
для удобства последующего автоматического импорта.
Далее, поскольку времени особо нет, но есть желание можно организовать
вялотекущий процесс разработки структуры предполагаемой базы.
Если начнется процесс выкладывания многие имеющиеся грабли
будут обнаружены и обнародованы.
Можно уже сейчас подумать о некоторых аспектах и потенциальных проблемах.
Например:
Предложения по организации исторических дат. (на опыте датирования фотографий кораблей). Данные предложения не обязательно
относятся непосредственно к хранению в базе - можно
организовать предварительную обработку, а в базу закладывать уже чистые диапазоны.
1. Очевидно, что тип данных любой СУБД нам не очень подойдет из-за
разнообразия вариантов дат, имеющихся в наличии - придется даты хранить или строками и самим их разбирать или диапазонами и разбирать их предварительно.
2. Поскольку заниматься мы будем русской/советской историей
то даты до марта 1918 года практически всегда на вход
поступают по "старому стилю".
Даты иностранных источников это не так -
для каждого источника нужно определить используемый календарь.
По умолчанию видимо русский.
3. Время, когда оно есть, можно или принудительно приводить к Гринвичу
или давать привязку. (точное время встречается очень редко
- в каждом отдельном случае стоит напрячься и сделать удобно)
4. Даты, известные приблизительно придется указывать диапазонами
навроде 1904-1905. Лучше указать широкий диапазон чем не указать
никакого.
5. Даты, популярные в литературе, как "около 1903 года" стоит
заменять на диапазоны, поскольку в виде ~1903 их использование затруднено.
6. Когда известен год - указывать год, известен месяц - указывать
месяц.
В результате каждая дата это диапазон между двумя точками +
возможно какие-то флажки указывающие на нестандартный календарь
или нестандартное время.
Примеры дат и их возможных записей
"август 1904 года" 08.1904
"15 сентября 1904 года" 15.09.1904
"около 1902 года" чешем репу и видим по смыслу
что это диапазон (напрмер для фотографии корабля в белой окраске)
1901-1903
"после 1917 года" опять же видим по смыслу что
царский герб например сбит, а корабль продали на металл в 1922 году
- диапазон 1917-1922
Вычитали в Таймс что немецкий крейсер пришел в Порт-Артур
такого-то февраля 1904 года - вычитаем 13 и пишем такого-то января
или пишем после даты символ G означающий григорианский календарь.
(что лучше не знаю - поскольку такие данные будут сидеть с обязательной
ссылкой на источник - где будет имется и календарь, используемый источником)
Пассажи типа "в 17.05 или в 18.00 по Токио" следует видимо сопровождать
идентификатором конкретного варианта поясного времени.
В итоге в любом случае каждая дата превращается в диапазон - 2 даты с точностью до секунды по Гринвичу в григорианском календаре - и по ним мы уже будем считать запросы.
Но с такими датами неудобно работать вручную - забивать лучше
читаемые варианты, описанные выше - главное чтобы можно было однозначто разобрать и привести к нормальному виду.
Итого:
Формат даты = (дата1) - (дата2) (как диапазон явный)
или (дата) как диапазон неявный
Можно формат даты подогнать под конкретное API конкретной платформы
чтобы парсить не напрягаясь, но лучше этого не делать ибо
платформы меняются. Также все равно придется что-то дописывать
для поддержки распространенных исключений.
Вариант
дата = DD.MM.YYYY HH:MM:SS [G] ["T"] (менее секунды не учитываем)
[G] - признак григорианского календаря, (по умолчанию юлианский до 1918 года)
прочие календари игнорируем - при желании можно будет дополнить
процедуру парсинга (то же касается и дат до нашей эры)
["T"] символ поясного времени - список их можно составить дополнительно
вместе с разницей с Гринвичем.
DD,MM,YYYY - день месяц и год
Год есть всегда.
Парсить это просто - ищем "-" - если есть - диапазон, нет одна дата.
потом для каждой даты выгребаем количество точек - если 2 то
это с днем, одна с месяцем - нет с годом. В зависимости
от ситуации тянем остальное.
Варианты когда нет например дня но есть время отбрасываем
- ибо информационной ценности нет.
Хрень типа "в полночь одного из мартовских дней 1904 года миноносцы" означает только 03.1904 и все.
Если у нас есть все до секунды - пишем в диапазон 2 одинаковых значения
иначе - даем интервал по тому что есть.
С датами есть несколько тонких моментов.
1. Все даты должны быть конвертированы в тип данных "дата/время" (datetime, smalldatetime, etc). Сравнивать строки с датами ни одна база на умеет (точнее умеет, но с непредсказуемым результатом :-))
2. Все даты должны быть приведены к единому стандарту. Никаких старых и новых стилей. Хоть от сотворения мира, хоть со дня рождения Джорджа Буша - но единообразно.
3. То же самое со временем. Хоть по Токио, хоть по Шанхаю - но в едином стандарте для всей базы.
4. И самое главное. Ни одна база не понимает неполных дат (вот бы где пригодилась троичная логика). То есть, к примеру, дата "1904 год" будет автоматически преобразована в "1 января 1904 года, 00 часов 00 минут 00 секунд". При этом в принципе невозможно установить, какая часть даты введена пользователем, а какакя сгенерирована сервером.
Вот одно из возможных решений. Не идеальное, во многом избыточное - но работать будет.
Итак:
1. Из основных таблиц убираются все поля типа "дата/время". Никаких "родился - женился - крестился - спущен на воду - продан на слом - съеден аборигенами".
2. Все подобные эпизоды хранятся как события в таблице "хронология". Событие - это любой эпизод, имеющий временную привязку. Спуск на воду крейсера "Баян", рождение адмирала Нельсона, женитьба прапорщика Ранцева на баронессе фон Засс...
3. Событие имеет одну временную отметку. Если требуется хранить какой-то интервал, событие разбивается на несколько отдельных событий. К примеру, бой Желтом море будет представлен десятком-другим событий, а вот выпуск гардемарина Ливитина мичманом - одним (пусть они хоть трое суток гудели по этому поводу :-))
4. Для каждого события в базе хранится:
- ключи ко всем вовлеченным в него сущностям (люди, корабли, флоты и т.п.) через систему промежуточных таблиц,
- дата и время события, пересчитанные в универсальный формат (скажем, григорианский календарь, время по Гринвичу),
- флаги достоверности для всех частей даты (скажем, год и месяц - достоверно, день и час - недостоверно),
- оригинальное представление даты или интервала в текстовом виде (для контроля, при запросах не используется),
- ссылка на источник.
Вот так или примерно так.
С уважением,
Роман