银行卡BIN数据全解析:从Excel清洗到MySQL导入与业务查询实战
2026/9/8 8:27:56 网站建设 项目流程

简介:面向支付系统开发、银行接口调试及风控建模等场景,这份银行卡BIN数据由银联官方于2020年4月25日发布,涵盖9868条记录,字段包括银行卡BIN、BIN长度、发卡行、银行卡名称、银行卡类型及卡长度等核心信息,是相关从业人员核对卡BIN与维护卡表数据的可靠依据。压缩包共7个文件,除系统文件外包含5个Excel分表(非标卡表、农民工卡表、跨行转账卡总信息、单位结算卡表、标准卡表),并额外提供已整理好的bank_card_bin.sql文件,可直接导入MySQL使用,Excel与SQL双格式兼顾人工查阅与程序化调用,整体体积仅1.12MB。目前已有3483人学习下载,适合需要快速获取官方权威卡BIN数据、搭建本地卡BIN库或校验交易卡类型的开发与测试人员使用。 银行卡BIN数据这五个字,做支付、财务、平台运营的同学应该都不陌生。日常处理交易流水、做对账、判断一张卡是哪个银行发的、是借记卡还是信用卡,靠的就是卡号前6到8位——也就是BIN。标题里这份“银行卡bin数据(Excel+MySQL)-2020最新最全-银联官方发布”,我拿过来完整跑了一遍,从Excel清洗、去重,到MySQL建表、导入、查询,最后接到业务查询接口里,过程不算复杂,但坑是真不少。这篇文章就把我的处理思路、操作步骤和踩过的坑完整写出来,给同样要处理这类数据的同学做个参考。

1. 你拿到的这份BIN数据究竟是什么——字段结构与应用场景

1.1 一张BIN数据表里到底有什么

先看字段。我拿到手的这份数据是Excel格式,核心列大概是这样的:卡BIN、发卡行名称、卡类型、卡组织、卡等级、是否国际卡,有的版本还会带卡号长度、数据版本日期。这里要特别提醒一句:卡BIN看起来是一串纯数字,但绝对不能按数字去处理,原因后面第五部分详细说。

卡BIN发卡行名称卡类型卡组织卡等级是否国际卡
622848中国农业银行借记卡银联普卡0
622575招商银行信用卡银联金卡0
4584412建设银行(示例)信用卡Visa白金卡1

再说说BIN和卡号的关系。银行卡号一般是13到19位,前6位是发卡行标识,但部分卡组织已经启用前8位作为BIN。判断一张卡归属于谁,本质就是用卡号前缀去和BIN表匹配。很多处理流程直接截取前6位,这在老版本数据上问题不大,但遇到8位BIN就会有误差。我的建议是先把数据表里的BIN长度分布统计出来,再决定业务侧用几位匹配,这个操作在2.2小节里细说。

1.2 这堆数据在真实业务里能干哪些事

这类数据最典型的应用场景有这么几个:

  • 支付通道路由:用户绑卡后,系统根据卡BIN判断走银联渠道还是外卡组织渠道,提前展示用户可能支持的卡种。
  • 财务对账和风控:核对银行流水时,通过卡BIN识别交易卡片的发卡行,标记可疑卡片来源。
  • 用户运营画像:识别用户持卡等级,比如白金卡、钻石卡用户,可以作为权益发放和客服分组的参考。
  • 数据产品测试:做支付网关、收银台演示,需要一批不涉敏的卡BIN样本数据。

“官方发布”的前提意味着这套数据的字段规范度和更新及时性,普遍优于网上零散手工整理的版本。但你要明白,即使是权威来源的整合版,也存在生成日期、字段口径差异的问题。标题虽写着2020,生产环境使用前还是要核对最新官方公开信息。把这套数据作为一个“基础底座”用,离线分析、内部系统开发、教学研学都没问题。

2. 动手前先做好数据准备:Excel清洗与去重

2.1 拿到Excel先别急着导入,先做这三步

我习惯拿到新版数据的第一时间不是双击打开,而是先复制一份备份,再对备份做整理。这样做的好处是原始文件始终没被动过,折腾坏了随时可以重来。

第一步,确认Excel文件本身的编码格式。如果直接用Excel打开CSV或从第三方导出的表格出现中文乱码,那不是数据错了,而是编码不匹配。我处理时一般先另存为xlsx格式,再用WPS或Excel打开,绕开CSV匿名编码问题。第二步,检查表头和字段顺序,把“卡BIN”“发卡行名称”“卡类型”“卡组织”这些列名统一英文或中文,后面导入MySQL会省很多事。第三步,筛选出空行、全空列,以及明显异常的重复数据,不要留着干扰后续导入。

这一步很多人会跳过,结果就是导入MySQL后报字段对不上、唯一键冲突、乱码等等连环坑。数据清洗阶段省下的时间,后面可能要十倍还回去。

2.2 用Excel函数快速做一次“体检”

清洗完肉眼可见的问题,再用Excel函数做一次体检,重点是检查重复和数据类型。我常用的是这样几个:

  • 查重复值:在数据旁加辅助列,输入=COUNTIF(B:B,B2),结果大于1的就是重复卡BIN,再配合条件格式把重复项标红,逐个确认。
  • 检查BIN长度:用=LEN(B2)查看BIN的字符长度,正常是6或8位。如果出现5、7、9这类长度,很可能是Excel自动去掉了前导0,或者把长数字转成了科学计数法。
  • 清理不可见字符:有些数据从网页或旧系统导出后,单元格里藏着换行符和空格,用=TRIM(CLEAN(B2))清洗一下再复制回去。
  • 数值格式化:选中BIN列,在“设置单元格格式”里统一改成文本类型,防止长数字自动变科学计数法。

做完这四步,再用数据透视表按发卡行名称统计一下行数,看是否有明显的大行缺漏。我实践中发现,很多整合版数据最大的问题不是字段不全,而是卡片类型归类混乱,比如同一家银行的借贷记卡名称不统一,所以尽量在做透视表时同时看“卡BIN+卡组织+卡类型”三个维度的组合。

2.3 版本和更新时间怎么判断

这类数据通常都带一个数据版本日期,有时在文件名里,有时在表格末尾。我强烈建议你把版本日期单独提出来,在Excel里加一列“data_version”,全部填上同一个值,比如2020版就填20200101或按文件生成日期填。将来如果拿到新版数据,导入同一个表,这列就能区分不同批次,不至于只能靠文件名回忆。

另外,发卡行名称、卡组织这些信息是随着市场变化更新的,所以任何版本的BIN数据都存在“过时”的可能。处理完数据后,把源文件的生成日期和渠道备注在记录文档里,几个月后再看会发现非常有用。

3. 把Excel数据落进MySQL:建表、导入与常见坑

3.1 先看一眼MySQL环境

导入之前,我建议先确认MySQL的版本和字符集配置。我用的是MySQL 8.0,全程在mysql命令行和MySQL Workbench之间切换。如果你是刚装好MySQL,注意安装时就把字符集设置成utf8mb4,或者安装后改/etc/my.cnf加入character-set-server=utf8mb4,否则后面存中文发卡行名称会乱码。

这里不展开安装教程了,网上MySQL安装配置的文章已经够多。你只需要确认三件事:MySQL能正常连接,root或当前用户有建表权限,本地能访问目标数据库。命令行里先跑一句:

mysql -uroot -p

输入密码后执行SHOW VARIABLES LIKE 'character_set_server';,看到utf8mb4或者utf8就基本达标。如果是latin1,先改配置重启再用,别急着导数据。

3.2 建表:字段类型怎么选才不折腾

表结构设计是整个环节里最值得认真想的一步。我建的表是这样的:

CREATE TABLE card_bin_info ( id INT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主键', bin_no VARCHAR(8) NOT NULL COMMENT '银行卡BIN号码', bank_name VARCHAR(128) NOT NULL COMMENT '发卡行名称', card_type VARCHAR(32) NOT NULL DEFAULT '' COMMENT '卡类型:借记卡/信用卡', card_org VARCHAR(32) NOT NULL DEFAULT '' COMMENT '卡组织:银联/Visa/MasterCard等', card_level VARCHAR(32) NOT NULL DEFAULT '' COMMENT '卡片等级:白金卡/金卡/普卡等', is_international TINYINT(1) NOT NULL DEFAULT 0 COMMENT '是否国际卡:0否 1是', data_version VARCHAR(32) NOT NULL DEFAULT '' COMMENT '数据版本日期', created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间', PRIMARY KEY (id), UNIQUE KEY uk_bin_org (bin_no, card_org), KEY idx_bin_no (bin_no) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='银行卡BIN基础数据表';

几个关键选择说下理由:

  • bin_no用VARCHAR(8)而不是BIGINT,是因为BIN虽然全是数字,但有的数据会带前导0,用数字类型直接丢失信息。
  • 唯一键uk_bin_org (bin_no, card_org)可以拦截相同BIN在不同卡组织下重复导入,比单纯bin_no唯一更合理。
  • 普通索引idx_bin_no是给后续业务查询加速的,因为实际查询永远是按BIN去匹配。
  • 引擎用InnoDB,支持事务和行级锁,将来做增量更新、批量删除都比MyISAM稳。

3.3 用LOAD DATA导入,别一条条INSERT

Excel文件本身不能直接LOAD DATA,所以要先把sheet另存为CSV格式。这一步有个小细节:另存时编码建议选UTF-8,而不是Excel默认的ANSI/GBK,后面MySQL侧少很多麻烦。

CSV准备好后,执行:

LOAD DATA LOCAL INFILE '/tmp/card_bin.csv' INTO TABLE card_bin_info CHARACTER SET utf8mb4 FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\r\n' IGNORE 1 LINES (bin_no, bank_name, card_type, card_org, card_level, is_international, data_version);

导入前先别忘了把CSV里的中文表头行处理掉,用IGNORE 1 LINES跳过。如果CSV是Excel生成的,行终止符通常是\r\n,就要用上面这个写法;如果是在Linux下用脚本生成的,行终止符可能只是\n,写错了会报列数不匹配。

如果执行时报错The used command is not allowed with this MySQL version,一般是本地加载文件这个开关没打开。解决方法:登录MySQL后执行SET GLOBAL local_infile = 1;,或者用MySQL Workbench的导入向导走一遍。数据量几万行的话,LOAD DATA几乎瞬间完成,比写程序逐行INSERT快几十倍,完全不是一个量级。

4. 落库之后怎么用:查询、关联与业务集成示例

4.1 单表查询:输入银行卡号识别发卡行

数据导入后,最常干的一件事就是输入完整银行卡号,识别出发卡行和卡类型。大多数人第一反应是截取前6位去等值匹配:

SELECT bank_name, card_type, card_org FROM card_bin_info WHERE bin_no = LEFT('6228480402564890018', 6) LIMIT 1;

这个写法对付只有6位BIN的库没问题,但如果表里同时存在6位和8位BIN,直接用LEFT截6位可能撞到不完整的数据段。我的做法是反过来,用完整卡号去LIKE匹配BIN字段,再按BIN长度倒序取最长的那条:

SELECT bank_name, card_type, card_org, card_level FROM card_bin_info WHERE '6228480402564890018' LIKE CONCAT(bin_no, '%') ORDER BY CHAR_LENGTH(bin_no) DESC LIMIT 1;

这个写法的好处是无论库里存的是6位还是8位BIN,它都会自动选最长匹配结果,避免截取位数不对带来的识别错误。缺点是无法走普通索引命中,但BIN表通常就几万行,全表扫描的成本其实很低。

4.2 与业务表关联的联表统计示例

如果业务系统里已经有一张订单表,里面存了用户卡BIN字段,想统计不同发卡行的交易分布,可以这样关联:

SELECT ci.bank_name, ci.card_org, COUNT(*) AS order_cnt FROM orders o INNER JOIN card_bin_info ci ON o.card_bin = ci.bin_no GROUP BY ci.bank_name, ci.card_org ORDER BY order_cnt DESC LIMIT 20;

这里有个前提:orders.card_bin的存储口径必须和card_bin_info.bin_no一致。如果订单表存的是卡号完整字段,可以先在查询里通过CONCAT和LIKE匹配;如果订单表存的就是6位BIN,而BIN表里有8位数据,联表就要按4.1节的思路处理,否则漏掉一批记录。所以我一般会在联表前先执行统计查询看下orders.card_bin的长度分布,再决定JOIN条件怎么写。

4.3 提供给后端接口的操作建议

BIN数据有一个非常鲜明的特点:数据量不大,更新频率极低,查询频率极高。这种数据放在MySQL里每次请求都查库,其实多少有点浪费。我通常的做法是,在服务启动时把整张表读入Redis缓存或进程内本地缓存,key设计成card:bin:{bin_no},value直接存发卡行和卡类型拼接字符串。

接口层流程很简单:

  1. 校验卡号纯数字,长度在12到19位之间。
  2. 依次按8位、7位、6位截取卡号前缀,去缓存中尝试获取。
  3. 缓存命中则直接返回发卡行信息;未命中再回源查MySQL,并写回缓存。
  4. 对确实不存在的BIN,也写一个空值缓存,防止恶意批量请求穿透到数据库。

只要表里数据量在10万行以内,这套方案非常稳,接口平均响应时间能控制在1毫秒级别。别想着把全表BIN数据天天放在MySQL里做复杂JOIN,这事更适合放Redis或者干脆放内存。

5. 常见问题与排查技巧实录

5.1 Excel打开CSV后全是###或乱码

表格显示成 #### 不是数据坏了,就是列宽不够,选中列双击边框自动调整宽度就行。乱码问题大多数是因为文件本身是UTF-8编码,而Excel直接用旧版方式打开了。解决方法是不要双击打开,而是用“数据-从文本/CSV导入”,在导入向导里明确选择UTF-8编码。如果WPS用户,通常在打开时会弹编码选择框,选对编码就能解决。

5.2 导入MySQL后中文发卡行名称全部乱码

这类问题十有八九是CSV实际编码和LOAD DATA声明的字符集不一致。如果你在Excel里另存CSV时选了“CSV UTF-8”,文件就是UTF-8;如果选了普通的“CSV(逗号分隔)”,文件大概率是GBK。我的排查顺序是:先用记事本或VS Code打开CSV看中文是否正常,再用CHARACTER SET utf8mb4导入;如果还乱,就把CHARACTER SET改成gbk再试一次。另外连接MySQL的终端最好设置SET NAMES utf8mb4;,否则命令行里显示正常,Workbench里却是乱码,或者反过来。

5.3 同一个卡号匹配出多个发卡行

这种情况通常是BIN数据里同时存在不同长度的段,比如622848有6位记录,也有8位记录,且8位记录的发卡行名称和6位不一致。排查方法是查一下重复的bin_no长度和来源,再决定规则。业务上优先信8位(更精确),如果8位没匹配上再退回6位。用我4.1节说的LIKE +ORDER BY CHAR_LENGTH(bin_no) DESC方式,一次SQL就能正确输出。

5.4 线上接口查询性能差

BIN查询性能问题基本都出在没用缓存、没用索引或者查询时做复杂函数运算。排查思路很简单:先看MySQL慢查询日志,再看SQL是否走索引。如果业务里经常用LIKE '%622848%'这种写法去反查,索引大概率失效,正确做法永远是“用卡号前缀去匹配BIN字段”,而不是在BIN字段上模糊匹配。性能还扛不住时,就该上Redis缓存或者本地内存表了,这个我在4.3节已经展开过,照着做就行。

最后再分享一个我自己坚持的习惯:每次处理完这类基础数据,我会把Excel源文件、清洗后的CSV、建表SQL、导入日志四件套放在同一个目录里归档,文件名统一带版本日期。MySQL表里也保留data_version字段,方便以后升级版本时用临时表导入、比对、再切换到新数据。整个过程最耗费时间的其实不是技术,而是清洗和验证这一步。把流程固定下来,下次再拿到任何行业的BIN数据或类似的基础码表,照着这个套路走一遍,基本不会再翻车。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询