答:后端作为数据库,有点直接把Mysql暴露在公网上供前端使用,会出现什么问题:I/O边界=>批量获取的性能考虑对数据进行count/sum等聚合,提前计算聚合结果。冗余字段组织边界=>安全考虑数据权限校验,防止非法访问校验业务规则。创建列表需要xxx领导的签名实现Backendasa“Database”,也就是回答上面的问题以及如何解决。User表Mysql/Postgresql的权限太粗了。必须是在Mysql/Postgresql之外的一层来验证权限。以下是挑战。解决B端权限,需要非常细致,不仅要到线,还要到格。权限可以按职位授予,也可以根据工单分配暂时授予。权限验证的开销不宜过大。如果用于C端业务,文档数量和用户数量可能会非常大。减少行级权限引入的开销。所以需要能够根据需要开启不同的授权模式。未登录的用户需要登录,或能够匿名浏览。如何为没有用户的访问促进适当的权限升级。非真人用户的访问,比如晚上的批处理,需要能够有机器人账号。账户的初始化是怎么描述的?谁将指定初始管理员?不同的用户表。这两个Project需要互相访问,应该使用什么User身份?解决了以上问题后,我们就得到了一个内置权限的“数据库”,可以开放到公网进行前端访问。在实际提取数据时,会使用人类用户自己的身份。只要用户对要访问的数据表或行有权限,就可以访问,否则不能访问。为业务数据表写一个Typescript类,然后建Mysql表。同JavaHibernate@Biz.profile('buyer','read')@Biz.profile('storemanager','read','create','update','delete')@Biz.profile('Administrator','read','create','update','delete')@Biz.authentic({rowPolicy:'public'})@Biz.publishedexportclassRegionFreightTmplextendsBiz.ActiveRecord{@Biz.lookuppublicreadonlyfreightTmpl:FreightTmpl;//计费模式:perpiece(目前只有perpiece)publicfreightTmplType:string;publicfirstPrice:number;publicfirstAmount:number=1;publicadditionalPrice:number;publicadditionalAmount:number=1;publicregions?:string;}查询的时候直接用这个类引用替换即可这个数据库表。视图表能做好权限校验的前提是只暴露单表的简单查询。那么如何处理count/sum/join呢?有没有必要发明一个SQL变种,然后搞SQL解析?一个简单的方法是引入“视图表”的概念。将这些聚合查询建模为虚拟视图表。这样查询的时候还是单表查询。解决了rpc请求时如何表达复杂查询的问题,避免了sqloverhttp,解决了权限验证难以确定目标是什么的问题。如果所有的聚合查询都是按需计算的话,物化视图表会很慢。通常我们需要按日期和维度预先聚合一些中间结果。这可以用物化视图表@(Biz.view`SELECTid,gender,age,city,SUM(OrderItem.cost)AStotalFROM${impactSet}JOIN${User}onUser.id=impactSet.userIdLEFTJOIN${Order}表示onUser.id=Order.userIdLEFTJOIN${OrderItem}onOrder.id=OrderItem.orderId`)@(impactSet`SELECTDISTINCT(Order.userId)ASuserIdFROM${Order}`)@(impactSet`SELECTDISTINCT(Order.userId)ASuserIdFROM${OrderItem}JOIN${Order}onOrder.id=OrderItem.orderId`)@Biz.source(Starriness,{dataSource:'clickhouse'})exportclassUserWithTotalextendsBiz.SqlView{publicreadonlyid:string;publicreadonlyuserId:string;publicreadonlycreated_at:Date;publicreadonlytotal:number;物化视图的问题在于何时刷新它们。通过在SQL中定义impactSet,我们可以通过mysqlbinlog触发clickhouse中物化视图表的刷新。用户行为表物化视图的来源是业务数据。用户行为因为数据量大,不适合直接插入mysql。为用户行为提供单独的宽表,记录用户进行了哪些操作。写入可以缓存在内存中,也可以像kafka一样通过队列缓存。宽表的列要根据业务需要进行扩展。如果业务关注的是用户操作的订单id或者产品id,需要添加这些字段。大概的api也类似于mixpanel等老牌分析厂商的报表接口。计算报表时,物化视图可以联合用户行为表和业务数据表得到分析结果。批量查询rpc往返并且只发送一个查询太慢了。支持一个数组并一次提交多个查询会很好。至于如何在前端代码中将多个组件的查询聚合到一个rpc中,这取决于前端数据查询框架是如何实现的。无非就是在全局设置一个缓冲区,在“合适的时候”刷新这个缓冲区,然后批量检查一次。存储过程的细粒度用户权限只能解决数据完全属于一个用户的问题。在很多情况下,数据是协作数据,有多个利益相关者,因此必须通过协商规则来修改数据,而不是用户说了算。例如,你可以决定今天的日记写什么,但你不能决定把今天的晚餐订单改成0。日记是你自己的,订单是多方关心的。解决业务规则校验后写入问题的是存储过程。前端同学肯定想用javascript写存储过程。其实就是所谓的FaaS的云功能。本质上,后端代码仍然存在,但是另一群人编写了它。如果业务规则比较简单,比如只是一个状态机的转换图,可以用配置代替代码。当然,大多数时候,对于复杂的业务逻辑,javascript是最直观的。如果数据迁移数据库的表结构发生变化,仍然需要编写SQL来升级数据库。标准做法没什么好说的。BackendasaDatabase使用RPC接口提供类似Database的东西,将后端业务分为User表/业务数据表/View表/物化视图表/用户行为表/Storedprocedure/DataMigration等预设概念。更规范除了“业务规则验证后写入”之外,其他后端接口不需要使用通用的编程语言,可以通过配置或者SQL定义来解决。这个解决方案既不是GraphQL也不是经典的BFF
