-- Add normalized customer phone storage and a unique index for duplicate protection. -- Safe to import on an existing database before/after the app code change. DROP PROCEDURE IF EXISTS apply_customers_phone_normalized_unique; DELIMITER $$ CREATE PROCEDURE apply_customers_phone_normalized_unique() BEGIN IF NOT EXISTS ( SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'customers' AND COLUMN_NAME = 'phone_normalized' ) THEN ALTER TABLE customers ADD COLUMN phone_normalized VARCHAR(8) DEFAULT NULL AFTER phone; END IF; UPDATE customers SET phone = NULLIF(TRIM(phone), ''); UPDATE customers SET phone_normalized = CASE WHEN phone IS NULL OR TRIM(phone) = '' THEN NULL WHEN REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', '') REGEXP '^[0-9]{8}$' THEN REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', '') WHEN REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', '') REGEXP '^0[0-9]{8}$' THEN RIGHT(REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', ''), 8) WHEN REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', '') REGEXP '^968[0-9]{8}$' THEN RIGHT(REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', ''), 8) WHEN REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', '') REGEXP '^00968[0-9]{8}$' THEN RIGHT(REPLACE(REPLACE(REPLACE(REPLACE(phone, ' ', ''), '-', ''), '(', ''), ')', ''), 8) ELSE NULL END; IF NOT EXISTS ( SELECT 1 FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'customers' AND INDEX_NAME = 'uniq_customers_phone_normalized' ) THEN ALTER TABLE customers ADD UNIQUE KEY uniq_customers_phone_normalized (phone_normalized); END IF; END $$ DELIMITER ; CALL apply_customers_phone_normalized_unique(); DROP PROCEDURE IF EXISTS apply_customers_phone_normalized_unique; -- Optional verification after import: -- SHOW COLUMNS FROM customers; -- SHOW INDEX FROM customers;