MariaDB中为何出现违反唯一约束的两行重复数据?
MariaDB唯一约束失效调试问题
我用JavaScript编写了一个应用程序,通过连接MariaDB服务器向两张表插入数据。首次运行程序时,房产表(property)和价格表(property_price)应保持1:1对应关系:一张表存储模拟房产数据,另一张存储价格数据,每个房产初始对应一条价格记录。后续价格变更时,一条房产可对应多条价格记录,但首次运行时绝对不应出现重复,且数据不能违反唯一索引——但目前确实出现了违反情况。
我怀疑是MariaDB配置或约束定义存在问题,以下是建表代码:
drop table if exists property_price; drop table if exists property; create table property ( unique_id bigint unsigned not null auto_increment primary key, web_id bigint unsigned not null, url varchar(256), street_address varchar(256), address_country varchar(64), property_type varchar(64), num_bedrooms int, num_bathrooms int, created_datetime datetime not null, modified_datetime datetime not null ); create table property_price ( property_unique_id bigint unsigned not null, price_value decimal(19,2) not null, price_currency varchar(64) not null, price_qualifier varchar(64), added_reduced_ind varchar(64), added_reduced_date date, created_datetime datetime not null ); alter table property_price add constraint fk_property_unique_id foreign key(property_unique_id) references property(unique_id); alter table property add constraint ui_property_web_id unique (web_id); alter table property add constraint ui_url unique (url); alter table property_price add constraint ui_property_price unique (property_unique_id, price_value, price_currency, price_qualifier, added_reduced_ind, added_reduced_date);
当前现象:
- DBeaver查询显示
property_price表存在两条完全相同的行(截图如下) - 唯一约束并非完全失效:再次运行应用时,会因尝试插入已存在的重复行而失败(但不是截图中的这组重复行)

调试建议
- 确认唯一约束的实际定义:执行
show create table property_price;,检查输出中的ui_property_price约束是否包含所有指定字段,确认字段类型、排序规则是否与表定义一致,避免因字段遗漏或类型不匹配导致约束不生效。 - 排查数据的隐性差异:不要仅依赖可视化展示,执行以下SQL查看重复行的实际字节内容,排查是否存在不可见字符(如空格、换行符、全角/半角差异):
SELECT property_unique_id, price_value, price_currency, price_qualifier, added_reduced_ind, added_reduced_date, HEX(price_qualifier) AS qualifier_hex, HEX(added_reduced_ind) AS ind_hex FROM property_price WHERE property_unique_id = [重复行的unique_id]; - 检查应用插入逻辑:
- 确认首次运行时,是否对同一个房产执行了多次价格插入操作,比如异步请求未做去重、事务未正确控制导致重复提交。
- 验证插入价格时是否正确获取了房产的
unique_id,是否存在重复使用同一ID插入多次的情况。
- 验证事务隔离级别:执行
SELECT @@tx_isolation;,若隔离级别为READ UNCOMMITTED,可能导致并发插入时约束检查失效,建议调整为MariaDB默认的REPEATABLE READ。 - 确认存储引擎:执行
SHOW TABLE STATUS LIKE 'property_price';,确保使用的是InnoDB引擎(MyISAM不支持事务级约束检查和外键)。 - 开启SQL日志排查操作:临时开启通用日志记录所有SQL操作,执行:
重新运行应用后,查询SET GLOBAL general_log = 1; SET GLOBAL log_output = 'table';mysql.general_log表,查看插入阶段的SQL语句,确认是否存在重复执行的插入请求。
内容的提问来源于stack exchange,提问作者user2138149
相关产品推荐
相关产品推荐

