Подтвердить что ты не робот

Поддерживает ли MySQL историческую дату (например, 1200)?

Я не вижу никакой информации об этом. Где я могу найти самую старую дату, которую может поддерживать Mysql?

4b9b3361

Ответ 1

Для конкретного примера, который вы использовали по вашему вопросу (год 1200), технически все будет работать.

В целом, однако, временные метки не предназначены для этого использования. Во-первых, ограничение диапазона произвольно: в MySQL это 1 января, 1000. Если вы работаете с материалами 12-13 века, все идет хорошо... но если в какой-то момент вам нужно добавить что-то более старое (10-й век или ранее), дата будет ужасно ломаться, и для исправления проблемы потребуется переформатировать все ваши исторические даты в нечто более адекватное.

Временные метки обычно представляются в виде необработанных целых чисел с заданным "интервалом тика" и "точкой эпохи", поэтому число действительно представляет собой количество тиков, прошедших с эпохи до представленной даты (или наоборот) для отрицательных дат. Это означает, что, как и любой фиксированный целочисленный тип данных, набор представимых значений конечен. Большинство форматов timestamp, которые я знаю о диапазоне жертвоприношений в пользу точности, в основном потому, что приложения, которые должны выполнять арифметику времени, часто должны делать это с достойной точностью; в то время как приложения, которые должны работать с историческими датами, очень редко нуждаются в серьезной арифметике.

Другими словами, временные метки предназначены для точного представления дат. Вторая (или даже фракция второй) прецессии не имеет смысла для исторических дат: не могли бы вы рассказать мне, до миллисекунды, когда Генрих 8-й короновал как король Англии?

В случае MySQL формат по определению определяется как "4-значные годы", поэтому любая связанная оптимизация может основываться на предположении, что год будет иметь 4 цифры, или что вся строка будет иметь ровно 10 символов ( "yyyy-mm-dd" ) и т.д. Это просто удача, что дата, указанная вами в вашем названии, все еще подходит, но даже полагаться на это все еще опасно: помимо того, что сама база данных может хранить, вам нужно знать от того, что может обрабатывать остальная часть вашего стека серверов. Например, если вы используете PHP для взаимодействия с вашей базой данных, попытка обработки исторических дат очень вероятно сбой в какой-то момент (в 32-разрядной среде, диапазон для временных меток в стиле UNIX - 13 декабря 1901 г. 19 января 2038 г.).

Вкратце: MySQL будет правильно хранить любую дату с 4-значным годом; но в целом с использованием временных меток для исторических дат почти гарантированно чаще возникают проблемы и головные боли. Я настоятельно рекомендую против такого использования.

Надеюсь, что это поможет.


Edit/дополнение:

Благодарим вас за это самое интересное ответ. Должен ли я создать свой собственный алгоритм для исторической даты или выбрать другой db, но какой? - user284523

Я не думаю, что у какой-либо БД слишком много поддержки для таких дат: приложения, использующие его, чаще всего имеют достаточное количество строк/текста. Фактически, для дат в году 1 и позже текстовое представление даже даст правильную сортировку/сравнение (при условии, что дата представлена ​​на порядок: y, m, d order). Однако сравнения будут нарушены, если также будут задействованы "отрицательные" даты (они все равно будут сравниваться как раньше, чем любые положительные, но сравнение двух отрицательных дат даст обратный результат).

Если вам нужны только даты года 1 и более поздние даты, или если вам не нужна сортировка, вы можете сделать вашу жизнь намного проще, используя строки.

В противном случае наилучшим подходом является использование какого-то числа и определение ваших собственных "интервалов тика" и "точки эпохи". Хорошим интервалом может быть несколько дней (если вам не нужна дальнейшая прецессия, но даже тогда вы можете полагаться на "реальные" (с плавающей запятой) цифры вместо целых чисел); и разумная эпоха может быть 1 января, 1. Основная проблема будет превращать эти значения в их текстовое представление и наоборот. Вы должны иметь в виду следующие детали:

  • Високосные годы имеют один дополнительный день.
  • Правило для високосных годов было "любое кратное 4" до 1582 года, когда оно изменилось с юлианского на григорианский календарь и стало "кратным 4, за исключением кратных 100, если они также не кратно 400".
  • Последний день юлианского календаря состоялся 4 октября 1582. На следующий день, первый из григорианского календаря, было 15 октября 1582. 10 дней были пропущены, чтобы новый календарь соответствовал сезонам.
  • Как указано в комментариях, два вышеперечисленных правила варьируются в зависимости от страны: папские государства и некоторые католические страны приняли новый календарь в указанные сроки, но многие другие страны заняли больше времени (последний из них был Терли в 1926 году), Это означает, что любая дата между папским быком в 1582 году и последним принятием в 1926 году будет неоднозначной без географического контекста и еще более сложной для обработки.
  • Нет "года 0": год до года 1 был годом -1 или годом 1 BCE.

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

Зная это, теперь вы выбираете подход, который лучше подходит вашим потребностям.

Ответ 2

В документации :

DATE

Дата. Поддерживаемый диапазон: "1000-01-01" '9999-12-31'.

Ответ 3

Да. Даты MySQL начинаются в 1000 году.

Ответ 4

Что бы это ни стоило, я обнаружил, что поле DATE MySQL поддерживает даты < 1000 на практике, хотя в документации указано иное. Например, я смог ввести 325, и он хранится как 0325-00-00. Поиск WHERE table.date < 1000 также дал правильные результаты.

Но я не решаюсь полагаться на < 1000, когда они официально не поддерживаются, плюс мне иногда нужны годы BCE с более чем 4 цифрами в любом случае (например, 10000 BCE). Поэтому отдельные поля INT для года, месяца и дня (как было предложено выше) кажутся единственным выбором.

Я бы хотел, чтобы тип DATE (или, возможно, новый тип HISTDATE) поддерживал полный диапазон исторических дат - было бы неплохо объединить три поля в один и просто отсортировать по дате вместо сортировки по year, month, day.

Ответ 5

Используйте SMALLINT год, поэтому год примет от -32768 (BC) до 32768 (AD) Что касается месяцев и дней, используйте TINYINT UNSIGNED

Большинство исторических событий не имеют месяцев и дней, поэтому вы можете запросить следующее:

SELECT events FROM history WHERE year='-4990'

Результат: "Ноев ковчег"

Или: SELECT events FROM history WHERE year='570' AND month='4' AND day='20' возвращение: "родился Мухаммад пбух"

В зависимости от требований вы также можете добавить столбец DATETIME и сделать его NULL для даты до 1000 и наоборот (таким образом, сохраняя несколько байтов)

Ответ 6

Это важная и интересная проблема, которая имеет другое решение.

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

Это можно сделать с помощью виртуальной машины Java (JVM), где время измеряется в миллисекундах относительно полуночи, 1 января 1970 г. UTC (Epoch), сохраняя требуемое значение как длинное в базе данных (включая отрицательные значения) и выполнения требуемого преобразования/вычисления на уровне компонентов после извлечения.

Например:

Date d = new Date(Long.MIN_VALUE);
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy G HH:mm:ss Z");
System.out.println(df.format(d));

Должен показать: Вс, 2 дек. 292269055 до н.э. 16:47:04 +0000

Это также обеспечивает независимость версий и платформ баз данных, поскольку он абстрагирует всю арифметику дат и времени в среде выполнения JVM, то есть изменения в версиях и платформах базы данных будут гораздо реже требовать повторной реализации, если вообще.

Ответ 7

У меня была аналогичная проблема, и я хотел продолжить передачу по дате полей в БД, чтобы я мог использовать поиск диапазона дат с точностью до одного дня для исторических значений. (Моя БД включает дату рождения и даты римских императоров...)

Решение заключалось в том, чтобы добавить постоянный год (пример: 3000) ко всем датам перед добавлением их в БД и вычитанием одного и того же номера перед отображением результатов запроса пользователям.

Если у вас в DB уже есть значение даты, не забудьте обновить возвращаемое значение с помощью нового номера константы.