我有一个rails 4应用程序,用户在其中定义一个tools
数据库,并创建存储品牌,年份等项目的字段。然后根据他们定义的字段在它们之前显示CRUD界面。
现在我的数据库模型如下所示:
class Database < ActiveRecord::Base
has_many :fields
和一个如下所示的字段模型:
class Field < ActiveRecord::Base
belongs_to :database
基本上,现在在“添加字段”页面上(在您创建了数据库并定义了字段之后),我正在创建一个唯一的ID并将其与该页面上的所有字段一起存储,然后我使用将字段分组为“行”(使用rails groupby语句)。
我有两个问题:
1.实施“数据库”是最有效的方法吗?
2.在使用CRUD界面中的字段创建数据库时,我无法弄清楚如何最佳地链接您定义的字段名称。例如,如果我在最初定义所有字段时创建name
字段,如何将其与CRUD界面中的字段相关联?
感谢您的帮助!如果我需要澄清更多,请告诉我们!
答案 0 :(得分:2)
我建议使用带有HStore扩展名的Postgres,因为ActiveRecord 4现在支持hstore开箱即用。
使用元数据设计存储属性值并不是非常有效的性能,并且一旦rails完成所有模型验证检查,更新就会变慢,所以我会避免它存储用户数据。
您仍然需要某种模式表来跟踪他们定义的用户属性/字段,包括其类型,显示名称,必需/可选等,以便您的应用程序可以正确验证输入并具有足够的信息来构建图。
但Postgres hstore运行良好,旨在处理用户定义的数据。 Postgres也支持对hstore列进行索引和查询,因此它不会很慢。
您的设计需要schemas
表和rows
表。
schemas
表将包含其所属用户的列,字段名称,显示名称,类型,范围等。
rows
表将包含其所属用户的列,以及值hstore列,用于保存用户在其架构中定义的所有值。
有关详细信息和操作方法,有很多简单的指南只是谷歌“hstore ActiveRecord 4”,因为官方文档似乎还没有赶上。
答案 1 :(得分:1)
我不知道你的商业模式,但我不知道是否制作一个全新的数据库是你的追求。 这看起来像是对键/值存储的需求。 postgres有一个hstore。
我会在数据库表上使用postgres hstore,其中每行代表一个数据库,而hstore包含代表每个任意字段的键/值列表。
答案 2 :(得分:1)
我不太清楚最终目标是什么,但你可以让你的Field模型包含名称,类型,价值和用户,这是与用户模型的关系。显然,1个用户有很多字段。
因此,假设用户Bob创建了“产品名称”和“产品价格”字段。他的用户界面会有“产品名称”和“产品价格”的文本框。价格框可能有一个下拉列表,表示“更少,更大,相等”,因为您知道类型是数字。因此,您的查询基本上会在伪SQL中选择“为用户Bob选择所有字段,其名称为”产品名称“,值为(或类似)产品名称文本框中给出的名称,名称为”产品价格“和值是(&lt; | = |&gt;)产品价格文本框中给出的值(解析为数字后)。
可能。
如果所有其他方法都失败了,请考虑编写您想要的代码。从代码到数据库结构而不是典型的其他方式非常有用。
希望有所帮助。
答案 3 :(得分:0)
由于某种原因,我无法附加数据库对象的类图,但试图从下面的表结构中获取它自己。
从最终用户的角度来看,他/她将在UI上查看字段名称列表。然后将它们中的一些放在UI上的某个独特位置以指示它们在一起。 这将形成一个新的数据库。我们看待它的另一种方式是,这只是桌子。 我参与了项目,我们尝试通过读取表定义来实现通过C#代码动态生成CRUD。 如果你看下面的图表,这可能会有一些疑问。基本上我们需要存储一些元数据表,代码可以使用那个构建CRUD。 下面是您可以开始的示例数据库对象。根据您想要的复杂和复杂的设计,您可以添加更多功能。
DECLARE @_DBField TABLE
(
ID INT IDENTITY NOT NULL
,NAME sysname NOT NULL
)
DECLARE @_FieldDataTypeID TABLE
(
DataTypeID INT IDENTITY NOT NULL
,SqlDataType sysname NOT NULL
,DisplayName sysname NOT NULL
)
DECLARE @_DB TABLE
(
ID INT NOT NULL
,DBName sysname NOT NULL
,FieldID INT NOT NULL
,DataTypeID INT NOT NULL
,IsPartofPK BIT NOT NULL DEFAULT 0
)
INSERT INTO @_DBField( NAME )
SELECT 'FName'
UNION ALL SELECT 'LName'
UNION ALL SELECT 'MName'
INSERT INTO @_FieldDataTypeID( SqlDataType ,DisplayName)
SELECT 'NVARCHAR(50)' ,'Short-String; Alphanumeric value'
UNION ALL SELECT 'NVARCHAR(200)' ,'Midium-String; Alphanumeric value'
UNION ALL SELECT 'NVARCHAR(500)' ,'Long-String; Alphanumeric value'
UNION ALL SELECT 'NVARCHAR(MAX)' ,'Max-String; Alphanumeric value'
UNION ALL SELECT 'INT' ,'Small-Integer; Integer Value'
UNION ALL SELECT 'BIT' ,'0 or 1; Boolean Value'
INSERT INTO @_DB( ID ,DBName ,FieldID ,DataTypeID ,IsPartofPK )
SELECT 1,'Student_Name',1,1,1
UNION ALL SELECT 1,'Student_Name',2,1,1
UNION ALL SELECT 1,'Student_Name',3,1,0
SELECT * FROM @_DB