因需求要实现动态表结构定义,其实是数据库软件做点活,非要编程实现。 想使用 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 文档,多看先人写的组件,总是有收获的。
第一,使用动态表列,编程复杂度会直线上升。 第二,建议使用冗余备用列替代,字段类型为字符串。 第三,如果需求简单,可以使用文档型字段替代,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 的确是方便,并且可以管理文件。
不明白用户为什么非要管理数据库结构。 如果要管理让他自己开发程序不就好了,干嘛还要你呢?
如果他开发不了,说明他真正需求不是管理表结构,你让他能自定义 item 就行了。
动态字段变成流,存入数据库中,附代码如下:
# 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 查询这个字段那是相当困难,另外维护成本高。
客户想用的是 wordpress 的 https://wordpress.org/plugins/advanced-custom-fields/ 插件这样的效果?