1
geelaw 2017-05-14 05:00:58 +08:00
A 方案怎么分页?每次重新返回整个链条?
如果可以保证 pid < id,那么用 B 显然可以很简单地处理分页。 另外如果数据出现不一致(譬如有环),如果用 A 会更容易导致后端崩溃,如果是 B 那么后端很难崩溃。毕竟,一个顾客心肌梗死和一个商店塌了相比,还是商店塌了更可怕一些。 还有另外的考虑:如果分级的层数是固定的,那么你的 model 可以变化为固定深度的,那应该用 A。 |
2
binux 2017-05-14 06:19:13 +08:00
我觉得你这个表首先设计就有问题,它天生带有一个需要递归查找所有的 children 的逻辑在里面。
如果你每次都要全读出来,那你还搞这个 pid 干嘛,直接存成 A 不就好了。 如果你要去遍历,难不成前端读完广东,还要再去读 where pid = 0 吗? 所以根本原因是你这个表设计得有问题。 |
3
think2011 2017-05-14 06:28:17 +08:00
跟前同事都是这样约定的
1. 前端负责展示,后端负责数据 2. 后端要是处理数据太麻烦,丢给前端整理 3. 前端要是运算数据太麻烦,丢给后端运算 基本上就 1 + 2,楼主的这种情况,通常是 2 的方案 |
4
ywgx 2017-05-14 10:10:31 +08:00
在安全性考虑的前提下,一般会尽量把计算量放到前端,分摊服务端压力
当然如果设计上前段解决起来,异常复杂,导致简单问题复杂化,就放在后端吧 这个灵活度比较大,还是具体项目具体实施吧~ |
5
reus 2017-05-14 10:30:31 +08:00 2
当然是 A,用 B 的后端也太懒了吧,什么都丢给前端。就想着自己有好处,想过前端怎么骂你吗?
前端要树,我就给树,前端要表,我就给表。分成两个 api。我不用 restful,一个 api 干什么的,我好好命名,不搞那套偷懒甩锅的把戏。 节省服务器资源?构造一个树,纯粹的计算,没有 io,能用你多少资源?找借口偷懒而已。 |
6
klesh 2017-05-14 10:50:53 +08:00 1
A
前端不应关心数据如何存储,既然这是一个树形结构就要返回一个对应的树形结构。后端应保持数据结构的统一表述和抽象隔离。现在是一个表结构,以后是一个文档结构呢?使用产后端分离最大的诉求之一是前端可能有无数个,从种类上分有 spa / mpa / iOS app / android app / 各种平台的 app。若在前端进行递归整理,工作量和维护量会增多。反之,你只要在后端维护一个树形结构,就可以节省很多前端的工作量以及可能出现的 bug。 1. 节省服务器资源的问题不存在,后端必须做 cache,否则只要有某一些前端 /app 调用不合理后端就跨掉? 2. 源数据结构不改页面就不用改?那要看你怎么定义源数据结构这个概念了。是从业务层面上去看这个问题,还是从数据库层面上去理解。 3. 我觉得可以用『去餐厅吃饭』这件事来类比这个事情。对于一个树形结构,直接返回原始底层数组,就相当于餐厅把原材料给你上上来,然后叫你自己拿回家去煮。 以上,你说的三条好处全部站不住脚,这不是后端偷懒的理由。即使你们要按哪端去处理比较方便,也得以『前端会有很多个 app 』这样的前提去考虑,以后端必须做 cache 为前提去考虑,以业务逻辑和关注点分隔的原则去考虑。 再扩展一下话题,若将来你们要集成第三方平台,然后他们的 location id 与你们的 location id 不一致要怎么处理?若『后端只给数据』这个是可以接受的话,然后是要把第三方的 id 也返回给前端,让所有的前端去处理吗? @geelaw location selection 最多做一个联动选择界面,为什么要分页?分页之后只有一部分的数据,如何正确重建树形结构(如何说某一个 parent 没返回来过,但它的 children 返回了)? @binux 有意思,表应如何设计? |
7
coderfox 2017-05-14 10:51:07 +08:00 via Android
原始数据的结构是树,只是数据库设计上表现为表,所以应该用树。
如果后端有压力可以尝试使用缓存。 我理解的前后端分离是:后端提供的接口呈现数据的原始模式。 |
8
reus 2017-05-14 11:10:08 +08:00
@binux 没问题,不需要递归,一般是把所有行读出来,构建树结构,然后返回客户端。这个树可以缓存起来。这样查询和更新都很方便。直接在数据库存树,更新不方便。
|
9
geelaw 2017-05-14 11:18:51 +08:00
|
10
ezreal 2017-05-14 11:18:56 +08:00
A
|
11
klesh 2017-05-14 11:53:19 +08:00
@geelaw
"所以我说如果 pid < id 且按照 id 升序返回那就不会有问题啊" 第一,即使你的假定可以做到,分页的意义在哪里?第二,你的假定根本不可能做得到,行政区的划分并不是一成不变的,一定会存在 pid > id 的情况:如新区成立, 老的村镇其 pid > id "为什么有根树的森林就一定要是递归的样式?有根树的森林不可以是符合一个约束的父亲数组存储?" 这里说的不是存储的问题,而是前后端数据结构交换的问题。前端不应关心后端如何存储数据,后端不应关心前端如何展示数据,两者之间通过合理的数据结构进行交流。 |
12
geelaw 2017-05-14 12:04:49 +08:00
@klesh
前一个问题:可以通过一开始取较大的 gap 避免,没说 id 必须是连续产生的;还有一种方法是准备另一个排序的 column,然后修改那个 column 以便以后按照“好”的顺序返回结果。(吐槽:行政区划这点数据还犯不着纠结这个问题,而且行政区划已经是有限层的问题了,不需要用这种组织形式存储。) “前端不应关心后端如何存储数据,后端不应关心前端如何展示数据” 这个和你说用 A 不是矛盾的么?按照这个想法,A 和 B 都没有天然的优势,因为 A 是按照前端想要展示的方式准备数据,B 是按照后端立刻就可以得到的格式准备数据。 或者可能是我对“展示”的理解和你不同?在我看来数据以一个特定的逻辑形式存储出来(例如按照某种对象的形式)已经算是“展示”了,最后出现在屏幕上的方式不重要,因为从数据的逻辑存储形式到人可以通过不同的介质(常见的:屏幕、声音、编程)。或者说我认为前端和后端对接的部分是 model,而不是 view / view model,前端可以自己把 model 变成别的 model、view model。 如果把“展示”理解为打印到屏幕上,那前端和后端之间的 gap 可太大了…… |
13
int64ago 2017-05-14 15:22:32 +08:00
这种问题都是前后端彼此太狭隘造成的,如果一个人前后端都写,就会很自然的选出代价最小最优雅的方式,作为后端出生的前端,我更希望跟懂点前端的后端合作,大家很清晰如何分工
对于狭隘的后端恨不得把整个数据库直接查出来丢出来,特别是用 Java 的,那些又长又臭的数据结构都是一坨一坨扔出来的(想保证一行 80 字符都难) 对于狭隘的前端恨不得拿到数据直接展视(既然后端给了数组,为何还要给个 length ?),后端应该是尽可能给出简洁的**元数据**,因为很多时候暂时的时候顺便处理的一些数据计算是很自然的,放后端需要额外处理 对于楼主的问题,我觉得应该放后端处理,倒不是考虑遍历的性能代价(其实这点计算双方代码量和执行效率都差不多)。因为这种结构有很强的依赖性,这种依赖性从前端看是完全由 pid 决定,而这个太不靠谱,如果数据结构重新组织,肯定是前后端都需要改了,而且 pid 的规则对于前端有点类似于魔法的感觉。再换一个大胆的构想,现在你用关系型数据库,于是很方便返回列表,后面假如换成了 mongo 呢,会发现直接返回递归形式更方便,而这些不应该是前端关心的 |
15
maomaomao001 2017-05-14 18:49:48 +08:00 via Android
lodash.js
|
16
sagaxu 2017-05-14 20:47:40 +08:00
我来提一个概念,中端,有的公司把中端归为后端,也有公司把中端归为前端,最有代表性的中端语言就是 php。
后端负责基础数据和基础业务逻辑的 API,中端组合后端 API 提供具体业务 API,并按前端的要求的格式返回。 |
17
fohuhu 2017-05-14 21:08:10 +08:00
有意思的帖子,公司目前也在谋划前后端分离
|
18
learnshare 2017-05-14 21:18:59 +08:00
前端不应该做类似数据库查询这种的动作,这增加了前端的复杂度,数据结构最好能够由后端处理完成。
当然,如果后端能够把数据库核心操作和 API 服务再分离一次,这种操作就有地方去了 |
19
x464744246 2017-05-15 09:11:00 +08:00 1
这种省市级 其实建议取消 pid 直接类似
id name 11 广东 1101 广州 110101 天河 类似 直接取位数匹配就好 |
20
x464744246 2017-05-15 09:11:36 +08:00
@x464744246 然后 就直接 B 方案
|
21
bengle 2017-05-15 15:10:08 +08:00
前端更偏向交互,后端更偏向业务逻辑。理论上应该是这样,但是现实中只能各种撕逼。。。所以需要一层前后端对接的中间层,后端保持一种数据结构输出,中间层把后端数据转成前端需要的结构,这个中间层可以后端搞也可以前端搞,我厂是前端做的,诶~
|
22
johnpang 2017-05-15 15:54:39 +08:00
[
{"1":{"name":"广东","pid":0}}, {"2":{"name":"广州","pid":1}}, {"3":{"name":"天河","pid":2-1}}, ] 在已知层级数的情况下这样会不会好点呢。。。 |
23
zioc OP @x464744246 实际业务类型并不是省市
@bengle 感觉现在前端做更合理,或者叫客户端 @learnshare 如果把前端换成 iOS/安卓客户端呢,应该客户端做吗 @sagaxu 这个沟通成本更高了,如果中端的工程师水平一般或者对接口质量没有追求,那简直是一场灾难。我前公司就有中间件。 @ywgx 比较同意,而且前端处理起来并不复杂 |
24
learnshare 2017-05-15 19:55:44 +08:00
@zioc 移动端也不做
类似的数据几乎是永远不变的,服务器生成一份缓存起来,以后就都是直接返回了,代价真的小 |
25
zioc OP @learnshare 如果数据是变得呢
|
26
learnshare 2017-05-16 10:12:07 +08:00
@zioc 变得也有理想的改变周期
比如估计一天才改动一次,那缓存 1 小时,改动后更新缓存。类似的设计 |