Лучший способ сделать это в MySQL - избегать хранения дат в виде строки в формате DD.MM.YYYY.Вместо этого сохраняйте даты в надлежащих столбцах DATE
, чтобы они соответствовали собственному формату: ГГГГ-ММ-ДД.
Решения использования STR_TO_DATE()
или других функций означают, что вы не можете использовать индекс для оптимизациисравнения.Поиск будет выполняться с низкой производительностью, поскольку он должен выполнить сканирование таблицы.
Ваш комментарий:
2 миллиона строк - это не большая таблица.Это не должно занять больше минуты или двух, чтобы реструктурировать его.Это будет только сложнее, если вы будете ждать, пока таблица не станет больше.
Поскольку ваши данные имеют неправильный формат, вы не можете просто изменить тип данных.Вот как я могу это исправить:
Шаг 1: Добавить новый столбец с правильным DATE
типом данных:
ALTER TABLE MyTable ADD COLUMN myDate DATE;
( ByКстати, не называйте свою таблицу «База данных» или столбец «дата». Это зарезервированные слова, и в любом случае они не являются описательными. Вы называете программные переменные «переменная»? )
Шаг 2: Создайте триггер, чтобы использование вашим приложением старого столбца автоматически копировалось в новый столбец:
CREATE TRIGGER InsMyDate BEFORE INSERT ON MyTable
FOR EACH ROW
SET NEW.myDate = COALESCE(NEW.myDate, STR_TO_DATE(NEW.oldDate, '%d.%m.%Y'));
CREATE TRIGGER UpdMyDate BEFORE UPDATE ON MyTable
FOR EACH ROW
SET NEW.myDate = COALESCE(NEW.myDate, STR_TO_DATE(NEW.oldDate, '%d.%m.%Y'));
Причина COALESCE будет понятна через мгновение.
Шаг 3: Заполните все значения в прошлых строках:
UPDATE MyTable
SET myDate = STR_TO_DATE(NEW.oldDate, '%d.%m.%Y')
WHERE myDate IS NULL;
Это нужно сделать только один раз.Все новые вставленные строки будут автоматически копировать правильное значение даты в новый столбец после создания триггеров.Любые строки, вставленные до того, как вы создали триггеры, будут иметь значение NULL в новом столбце, поэтому вам нужно ОБНОВИТЬ их, как показано выше.
Шаг 4: Измените код приложения, чтобы любая ссылка настарый неправильный столбец даты использует новый столбец даты.Обращайтесь к любому INSERT, UPDATE или SELECT, который ссылается на дату.Протестируйте и разверните это изменение кода.
После того, как вы это сделаете, любой INSERT или UPDATE будет указывать значение в новом столбце даты вместо NULL.Это фактически сделает триггер неоперативным, потому что не-NULL-значение в myDate будет иметь приоритет над выражением STR_TO_DATE ().Это позволяет вам развернуть код по вашему усмотрению, и база данных просто будет продолжать делать правильные действия с вашими данными.
Шаг 5: Удалите триггеры и старую строковую датустолбец:
DROP TRIGGER InsMyDate;
DROP TRIGGER UpdMyDate;
ALTER TABLE MyTable DROP COLUMN oldDate;
Если вы обеспокоены тем, что каждый ALTER TABLE будет блокировать таблицу во время реструктуризации таблицы, вам следует научиться использовать pt-online-schema-change .Это позволяет вам выполнить ALTER TABLE без блокировки (за исключением краткого момента в конце реструктуризации).