RT。。我是通过 PHP 的 pdo 方式来获取 mysql 的返回值的。其实也没什么特殊的使用场景,就是想写一个注册功能,注册时让用户知道是哪个参数重复了(比如用户名、电话、邮箱)等这些不允许重复的字段。因为默认 mysql 只会返回 23000 错误码,并不会返回具体哪一个字段重复了。
考虑过先 select 多条件查找,发现了后返回给 php 提示用户,如果没发现有重复的内容则再使用 php 访问数据库写入,但这样就访问了数据库 2 次了,对性能不太友好,也不优雅。可能是我比较笨吧,想来想去没什么好办法。
原谅我只是个前端,对 sql 只会简单的读写。虚心请教一下,是否有 SQL 语法可以做到。
1
thread2 2018-06-19 21:25:02 +08:00 via Android
用户填完“用户名、电话、邮箱”后,点击提交前,异步查询下,如果重复则提示,如果不重复则允许提交
|
2
mostkia OP @thread2 恩,感谢你的回答,这也是一个思路,这样的话鼠标离开输入框,激活一个 ajax 事件,后台直接 select 当前输入框参数,就能知道哪个重复了,而后台使用唯一约束让前台进行这方面的过滤也不会存在安全问题。但性能方面应该和我的方法差不多吧,区别只是一个放在前台分散验证,而我的方法是上传后在后台集中验证。如果能一次访问是不是更好呢?
|
4
soho176 2018-06-19 22:57:19 +08:00
这不就是每个网站 最基本的注册功能吗
|
5
torbrowserbridge 2018-06-19 22:58:43 +08:00
获取并解析 mysql 的错误信息可实现。不过代价大了一点。
|
6
watzds 2018-06-19 23:00:52 +08:00 via Android
这有啥性能问题,注册量这么大就好了
|
7
letitbesqzr 2018-06-19 23:04:32 +08:00
我们项目是绝对不允许这些错误让 mysql 处理的,加唯一约束只是为了查询速度,事先用代码一个个的条件的判断好,有一步错误就返回,sql exception 属于是绝对意外的异常了。
|
8
947211232 2018-06-19 23:12:46 +08:00
应该有获取错误信息的函数方法的,否则真的不可思议了——根据错误信息设置你要返回前端的消息提示
|
9
mostkia OP @watzds @letitbesqzr 恩,也就是说,让 mysql 一个一个条件的 select 这样查找,数据库时可行的是吗?如果这样的话,假设有 3 个字段需要判断(一般都至少有 3 个,邮箱,用户名,电话等),那至少要读写数据库 4 次( 3 次判断,没问题写入 1 次),高并发情况下我觉得也太多了。。当然注册一般没那么多并发,只是对于数据库这样使用还是心存疑惑,感觉这种方法好笨...哈哈,可能是我太多虑了吧。回头写一下吧,出问题再说。。感谢所有回答的朋友了。
|
10
msg7086 2018-06-20 01:02:43 +08:00
> 访问了数据库 2 次了,对性能不太友好
能不能说说访问两次对性能产生了多少影响? |
11
msg7086 2018-06-20 01:11:31 +08:00 1
你看,数据库如果放在 SSD 上跑的话,1000qps 轻轻松松。假设其中有 50qps 分给注册,那你一秒钟能承受 25 个新用户注册,一天下来可以跑 100 万新注册用户,一个月就是 3 千万。
你要有了 3 千万新用户,不买个更好点的服务器么…… 数据库优化的时候去关注这种带索引查询的性能意义很小。N+1 或者无索引查询优化才是应该关注的地方。 |
12
mostkia OP @msg7086 我只是觉得可能有更好的办法,毕竟新手,有时候对自己想到的办法还是不太自信,结果似乎大家都是和我一样的做法,那我也没什么问题了,直接这样老老实实一步一步判断就行了。性能问题也是我想当然的,理解肯定不及各位常年使用数据库的大佬,还是谢谢各位解答的朋友了。能百忙之中回答我的问题就很感谢了。
|
13
q397064399 2018-06-20 09:02:18 +08:00 1
@mostkia #12 原谅我爆个粗口,, 扯什么鸡巴蛋的性能问题,MySQL 单表少于 5 亿,不要瞎几把谈性能问题,有空可以去研究其它的东西,内存回收 分布式系统,在代码层面上依赖数据库的报错机制本身就有问题,能在应用层干掉的 就要在应用层干掉,数据库是存储数据的,不是给你弄业务逻辑的,最烦那种写存储过程的,这种东西本来就应该是应用干的事情,职责要明确。
|
14
liuzhedash 2018-06-20 09:07:34 +08:00
@mostkia #9
胸弟,只要你正确加了索引就完全可行,乘以 10 都没问题。 |
15
hand515 2018-06-20 09:47:20 +08:00
怕网络次数多影响性能,那就用 union all 或者 OR 查询,一次提交
|
17
mostkia OP @q397064399 额。。这位兄台可能对数据库有着很深的执念啊....又难道我是发了一个不可理喻的问题?我虽然只是个前端,对于数据库设计也并不熟悉。但追求更好的写法,避免自己一个人造轮子踩坑应该没什么原罪吧。。依我的看法,不要说 5 亿数据的表了,表的优化没事先做好,数据量能超过百万还能用就很看人品了,数据库的优化应该事先做好,而不是等到出性能问题了再改表,到时候可能数据多了也不好改的,所以就请教一下而已。。。
结贴了。结贴了,手动下沉。。一直挂在顶部,指不定等一下又碰到几个暴躁老哥呢。。 =_= |
18
mostkia OP @liuzhedash 好的,谢谢,已经按照楼上几位大佬的方案写好了控制后台了。。
|
19
msg7086 2018-06-20 15:45:59 +08:00
@mostkia 数据库优化其实不需要「事先」做好,而是应该跑起业务做压测以后再看哪些地方是性能瓶颈,然后再集中优化。你现在思考的问题属于过早优化,90%的场景下是浪费时间,剩下最多 10%碰巧被你优化上了。
记住这句话: Premature optimization is the root of all evil. |
20
mostkia OP @msg7086 基础的应该做好准备吧,比如加索引什么的。我查资料的时候,看到翻车的太多太多了,都是一开始写的不好,然后到处问。。唉,也是看怕了。随便从浏览器历史记录里翻出来了几个案例...
https://bbs.csdn.net/topics/90035915 https://bbs.csdn.net/topics/392091851?page=1 他们的数据库 10W 条就炸了。所以按这些案例来讲,我仍旧认为初期那些基础的优化还是有些必要的。当然这不是这个帖子要讨论的主题。。这个帖子似乎讨论方向一直朝着奇怪的方向前进着。。掰都掰不回来,其实我已经在 12、18 楼接受了各位大佬的看法并已经明确放弃使用 sql 语法来写了,转而使用 php 直接做逻辑层,现在代码都写好了,但关于性能的讨论却没断过,哈哈,感觉自己是在钓鱼,也是 6 的不行。 |
21
mostkia OP 可能也是自己的说法有问题吧,明明只是想求一个 sql 语法,但却去强调了一下性能,其实性能倒是其次,我只是觉一个一个的 select 得这个方法实在是太笨了而已,需要多次请求数据库,从而连带的做了性能方面的猜想(其实就是我不了解数 mysql 据库造成的)但到最后这帖子变成了完全的性能方面的讨论,也实在是超出了我的预期。。而回复 sql 语法的也只有 16 楼。哈哈,尴尬了。。当然各位大佬说的都是经验只谈,比我瞎猜的肯定要靠谱,我个人感觉也的确有所收获,至少以后不会再去纠结性能问题。
|
22
msg7086 2018-06-20 23:50:23 +08:00
@mostkia 加索引随时都可以加,一般看慢查询日志就行了。
前期加索引也不见得就是好,因为索引除了读取收益以外,还有写入开销。 有时候你甚至会发现加了索引后比原来还慢的。 还是要具体分析具体解决。 至于 10 万炸,这种是因为「不懂」,而不是因为「没有加索引」。 这种「不懂」的人,就算一开始就加上索引,性能也会一样一团糟。 因为你的语句可能压根就用不上你点开的索引。 至于第二个帖子,你看,那么长的 SQL,恰恰是 13 楼说的把数据库当成运算器来跑的典型案例。 这种如果全部转换成单个查询(就是你说的访问数据库多次的方法)反而性能会好得多。 这帖子的本质问题还是在优化,提出的问题是很值得深思和讨论的,我觉得比单单一个 SQL 语句要有价值得多。 |
23
mostkia OP @msg7086 也是,对于我这个程度的,能用就好,不用太纠结这些事情,毕竟接触数据库的机会也不多,慢日志和类二进制日志也完全没去了解过,哈哈。不过现在程序也写完了,跑起来也不错,也不管这破事了,有时候写代码往往会去纠结一些奇怪的地方,现在想想,不就是多几次查询嘛,怕网络性能问题集中在一起让后台查询即可。这帖子也让我对数据库在用法上有了更多了解。至少对使用上的误区有了大致的概念。
其实我更想在项目中使用的是 MongoDB 这类非关系数据库,写法比较接近前端常用的 json,对前台更友好一些,但无奈项目使用什么程序不是我说了定的,哈哈有些遗憾。再次谢谢所有回答的朋友了,不管是批评的还是指点的。结贴吧,结贴吧。认真脸  ̄▽ ̄ |