新手问题 Rails 如何动态定义表结构?已上传了我的方法。

yan32768 · 2015年07月21日 · 最后由 yan32768 回复于 2015年07月25日 · 4830 次阅读

因需求要实现动态表结构定义,其实是数据库软件做点活,非要编程实现。 想使用 migration,但又不知点如何下手,rake db:migrate 是不是可以在程序脚本中执行呢,对 rake 也不了解。 谁能给指点一下,究竟怎么做呢?下面是我的尝试

这里的动态表是用户自己定义表结构,自己维护表中的数据,能自定义查询。其中最麻烦的是创建表。

查到 rails 支持表结构的维护模块 ActiveRecord::ConnectionAdapters::SchemaStatements,下面是用法

获得连接,是一个 ActiveRecord::ConnectionAdapters 实例,需要进一步考虑配置问题,用户名,表空间应先定义好。 conn=Userinfo.connection 获得数据类型标识 keys 是 ruby 的数据类型符号列表 types=conn.native_database_types.keys 将创建表列的块先定义好,都需要是动态方法实现 p=->(t){t.send(types[1],:name,limit:60} 这一步是创建表,《ruby 元编程》中说 send 方法不能以块为参数,但的确可以用。 conn.send(:create_table,:test_table_name,&p)

关于连接可以先确定连接设置参数, class Book < ActiveRecord::Base establish_connection "library_db" end "library_db"是在 yml 里定义好的,对于不同表空间,需要支持不同账号进行默认设置,这些都不需要用户考虑。

总结一句:多看 rails 文档,多看先人写的组件,总是有收获的。

想到一个笨办法,就是手工去生成 migration 文件,然后调用 shell rake 命令,不知道行不行

需求一定是要在 sql 数据库上做动态表列吗?就不能用 nosql 的 mongo 这些?

第一,使用动态表列,编程复杂度会直线上升。 第二,建议使用冗余备用列替代,字段类型为字符串。 第三,如果需求简单,可以使用文档型字段替代,PostgreSQL 的 JSONB 字段性能不错。

migration 是用来在版本升级的时候追踪数据库变更的。 直接调用 migration 原则上不需要单独写 migration 文件,而是直接在数据库上 create table / alter column 就行了吧。

#5 楼 @lidashuang #6 楼 @lb563 #2 楼 @alucardpj 多谢各位,客户让用 oracle 10g,我想了个最简单的方法,拼接出 DDL 语句,当一般 sql 执行。这样绕过 rake,应该行得通。 mongodb 看看简单教程,的确是个好东西,不用管数据类型,不用建表,没用过,不知道能不能做多表关联查询什么的,有没有坑,做保留方案吧

我觉得还是再分析一下需求,是不是真的需要做动态表列,如果增加表列,老的数据如何处理?如果是删除列,老的数据是否也要删除列? 按我的理解,这种动态属性的表结构可以转换成一对多的从属关系分两张表保存,且这两张表都是固定列的,这样每条记录的属性都可以不一样,顶多再加一个表列的描述表,就能满足需求。只是需要在代码层面做额外的数据校验。

#8 楼 @alucardpj 多谢,不是做动态列,是用户要自定义建立数据模型,相当于用数据库工具建表。对于修改和删除列,当然能保留的数据就保留了。我做的项目并不是论坛,可能不符合 mongodb 的适用场景。但是在数据管理方面,用 mongodb 的确是方便,并且可以管理文件。

没有正确挖掘客户需求也是开发者的锅。

前几天问到横向任意扩展用的数据库,社区里清一色的都说不要用 mongodb,推荐 pg。再学 pg 的 jsonb 格式真的是累觉不爱啊……

动态建表不太适合用 sql,如果要用,就用 EAV 模式。

  1. Mongodb 等 schema-less 的文档 db
  2. EAV 模式
  3. 主键+JSON 字符串,当 KV 用。

#14 楼 @yan32768 一种让人脑洞大开的模式。。entity-attribute-value。。。。。就是高级版的 K-V。。。

#15 楼 @est 感觉能用到 EVA 的需求也是脑洞大开模式.. 目前还没有遇到必须动态表结构的需求。

#16 楼 @hooopo 能唯一举出例子就是 Magento。。。商品附加属性用 EAV 保存的。其实保存为一段 json 字符也行。

#16 楼 @hooopo 有这样的需求,用户想管理数据,又不明确或不想让你知道管理的具体内容。

不明白用户为什么非要管理数据库结构。 如果要管理让他自己开发程序不就好了,干嘛还要你呢?

如果他开发不了,说明他真正需求不是管理表结构,你让他能自定义 item 就行了。

#19 楼 @nine 用户想要自己建表,然后可以查询、导入数据,增加、修改或删除数据,但用户并不了解数据关联的复杂性,或者用户不需要做复杂数据的维护。我要做的项目类似于元数据管理。

动态字段变成流,存入数据库中,附代码如下:

# Serialize a preferences attribute.
class User < ActiveRecord::Base
  serialize :preferences
end

# Serialize preferences using JSON as coder.
class User < ActiveRecord::Base
  serialize :preferences, JSON
end

# Serialize preferences as Hash using YAML coder.
class User < ActiveRecord::Base
  serialize :preferences, Hash
end

然后在程序中动态解析流为对象。 对象中的属性可以动态的增删改。缺点就是利用 SQL 查询这个字段那是相当困难,另外维护成本高。

#21 楼 @cuihq 感觉和 mongodb 类似,虽然可以实现,但还是想按标准关系数据库模式做,用户懂数据库,未必懂里面的字段格式。

客户想用的是 wordpress 的 https://wordpress.org/plugins/advanced-custom-fields/ 插件这样的效果?

#23 楼 @vkill 就是做到表结构自定义,可以在动态表上做增删改查,使用传统 E-R 关系数据库模型,可能大家都想多了,这个时期似乎所有东西都要和 json,js 套近乎,但的确不是我想要的东西。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号