程序大部分逻辑可以用 sql 来实现,不知道和用代码实现哪种更有效率

2017-03-10 17:07:55 +08:00
 smdxex
程序大部分逻辑可以用 sql 来实现,不知道和用代码实现哪种更有效率

比如贪吃蛇大部分核心逻辑

//初始化形状
iniSnake(arr) ----->sql "insert arr 9 x=rownumber, y =9 " arr 表添加 9 行,一行代表一个点
//绘画形状
drawSnake(arr) ----->sql "select x,y=>drawPoint(x,y) from arr " 绘画形状 drawpoint 需要自己写

//检查是否有重合点
CheckSnake(arr) ----->sql "select count (*)> 1 arr a inner join arr j on (a.x=j.x) and (a.y=j.y) " 检查重合点
4642 次点击
所在节点    程序员
33 条回复
msg7086
2017-03-14 07:44:13 +08:00
以下是你那些 SQL 代码的 Ruby 函数式风格转写:

INSERT arr 9 x = rownumber, y = 9

9.times { |x| arr << {x: x, y: 9} }

SELECT x,y=>drawPoint(x,y) FROM arr

arr.each { |x:, y:| draw_point(x, y) }

SELECT count (*) > 1 arr a INNER JOIN arr j ON (a.x=j.x) AND (a.y=j.y)

arr.group_by(&:itself).select{ |point, group| group.size > 1 }.keys
smdxex
2017-03-14 08:07:58 +08:00
@msg7086 现在没有人在逻辑中使用, group , select 等在 c#, java ,等语言中,
arr.group_by(&:itself).select{ |point, group| group.size > 1 }.keys
这个是说处理集合得话,我得意思就是这样,但是包括链接查询和所以 sql 可以处理集合
msg7086
2017-03-14 08:17:23 +08:00
@smdxex 那就……用个好点的语言呗?
C#的 LINQ 是支持 Group 和 Select 的(分别是 #GroupBy 和#Where ), Java 不懂就不说了。
所以我之前就说了,你说了半天的 SQL 其实只是函数式风格编程的某种表达,你的关注点应该在函数式风格上,而不是 SQL 上。
现在我们做开发都已经不写 SQL 语句了,都是用函数式风格来写逻辑,然后交给 ORM 去转译成对应的 SQL 。
直接写 SQL 其实开发效率是偏低的。
smdxex
2017-03-14 08:22:36 +08:00
@msg7086 你没有搞懂我得意思,你一直说得是操作数据库得逻辑,我说得是,一切可以程序逻辑,可以用 sql 类似语句
来表达,比如,我弄了好几个游戏,发现这些游戏 6-7 成逻辑,可以写成 sql 语句来表达, sql 抽象度更高,所以效率更高
msg7086
2017-03-14 08:29:24 +08:00
@smdxex 是你没有搞懂我的意思。
我上面根本就没有提到任何一个数据库,示例的操作全都是在数组上进行的。
你如果把你那些 SQL 语句都写成函数式表达,你会发现不仅抽象度好,而且表达力更强,开发效率比 SQL 更高。

SQL 的表达力已经很弱了,所以 Rails 框架才把 SQL 抽象起来,更好地用代码来表达。
而你现在等于是在开倒车,倒退回用 SQL 的年代。
smdxex
2017-03-14 08:50:38 +08:00
@msg7086 我得意思是,这种 sql ,可以代替
90%循环,但是我从来没有听说过,不写循环得程序
msg7086
2017-03-14 08:52:28 +08:00
@smdxex
再举个栗子好了,假设有如下的本地变量和类型:
Gamedata = {Mob, Persons}
Person = {HP, MP, Money, Bag}
Bag = [Items]
Item = [Name, Count]

现在要找出所有身上带着至少 5 个大师球的所有玩家。

你眼中别的程序员的代码:
MatchedPersons = []
for i = 1 to Gamedata.Persons.size
..person = Gamedata.Persons[i]
..items = person.Bag
..count = 0
..for j = 1 to items.size
....item = items[j]
....if item.Name == '大师球'
......count = item.Count
..if count >= 5
....MatchedPersons += person

你眼中的代码:
SELECT DISTINCT Persons FROM Gamedata.Persons JOIN Items
WHERE Persons.id = Items.person_id AND Item.Name = '大师球' AND Item.Count > 5

别人眼中的代码:
Gamedata.Persons.select { |p| p.Bag.any? { |i| i.name == '大师球' && i.count > 5= } }

如果你没听说过,那就去听说一下呗……
msg7086
2017-03-14 08:53:27 +08:00
上面代码手滑了,两处应该是 >= 5 。
smdxex
2017-03-16 08:28:57 +08:00
@msg7086 以前你们根本没有发现, sql 这种表达方式,可以写游戏,写 app,写企业应用关系少得,本地应用,
msg7086
2017-03-17 09:51:32 +08:00
@smdxex 哦嚯,你是全球第一个发现的啊,好棒哦。

反正我们早就淘汰这种低效率的表达方式了,你开心就好。
smdxex
2017-03-17 11:21:20 +08:00
@msg7086 是你开心,聊以自慰就好吧
smdxex
2017-03-17 11:23:11 +08:00
我说得这个东西,其实是微软很早前提出得, dsl 语言得,改进版本,换了一个表达方式,你们就自慰起来了?
beetlerx
2017-03-19 12:00:03 +08:00
你要是搞着玩,随便怎么方便怎么来,要是分布式应用,一般把逻辑放在代码里,就是尽量把压力放在应用端而不是数据库端,因为一般应用横向扩容比数据库扩容简单的多,出现问题了直接大不了重启,数据库要是挂了就不好玩了

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/346506

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX