如果我定义一个Customer和Order模型,其中Customer"有很多" Orders和Order"属于" Customer,在Rails中我们谈论Order有一个外键到Customer通过customer_id但我们并不是说这是在数据库中强制执行.
由于Rails没有将其定义为数据库级约束,因此存在数据完整性被违反的风险,可能在应用程序之外(或者如果同时收到请求,则在内部?),除非您手动在数据库中强制执行约束.
为什么Rails没有在数据库级别定义外键,或者有没有办法让Rails这样做?
class Customer < ActiveRecord::Base
has_many :orders
end
class Order < ActiveRecord::Base
belongs_to :customer
end
ActiveRecord::Schema.define(:version => 1) do
create_table "customers", :force => true do |t|
t.string "name"
end
create_table "orders", :force => true do |t|
t.string "item_name"
t.integer "customer_id"
end
end
Run Code Online (Sandbox Code Playgroud) 设置外键约束的常用方法是选择外键指向哪个表.
我在1个表和一组表之间有多态关系.
这意味着该表将与集合中的其中一个表有关系.
例如.
images: person_id, person_type
subordinates: id, col1, col2...col9
products: id, colA, colB...colZ
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,如果person_type是"subordinates",那么person_id应该是subordinates.id的外键,并且产品也是如此.
所以我想知道,是否有可能将一个外键用于其中一个表,或者你必须专门设置它在指定一个表时指向哪个表.
这个问题适用于MySQL和PostgreSQL.
谢谢
我们在应用程序中使用多态关联.我们遇到了经典问题:我们遇到了无效的外键引用,我们无法创建外键约束,因为它是一个多态关联.
也就是说,我已经做了很多研究.我知道使用多态关联的缺点和好处.但我发现似乎是一个不错的解决方案:
这很好,因为你可以获得两全其美.我担心的是数据重复.我对postgresql没有足够深入的了解,无法完全理解这个解决方案的成本.
你的想法是什么?这个解决方案应该完全避免吗?或者这是一个很好的解决方案?
在我看来,唯一的选择是为每种关联类型创建一个外键.但是你会遇到验证只存在一个关联的问题.这是一个"挑选毒药"的情况.多态关联清楚地描述了意图,也使这种情况变得不可能.在我看来,这是最重要的.数据库外键约束是幕后功能,改变"意图"以使用数据库限制对我来说是错误的.这就是为什么我想使用上面的解决方案,假设它没有明显的"避免".
在类似的应用程序,以计算器,我建设,我想决定什么关系我的Questions,Answers和Comments表应该有.
我可以拥有Questions并且Answers都由一张桌子代表Posts.
这将允许Comments有一个外键Posts.
但是,如果Questions并且Answers是单独的表,那么Comments这些表中应该有什么关系呢?
更新:尽管所选答案建议使用类表继承方法,这似乎是数据库术语中的最佳方法,但Rails ORM不支持此选项.因此,在Rails中,我的模型必须使用单表继承,并且可能如下所示:
class Post < ActiveRecord::Base
end
class Question < Post
has_many :answers, :foreign_key => :parent_id
has_many :comments, :foreign_key => :parent_id
end
class Answer < Post
belongs_to :question, :foreign_key => :parent_id
has_many :comments, :foreign_key => :parent_id
end
class Comment < Post
belongs_to :question, :foreign_key => :parent_id
belongs_to :answer, :foreign_key => :parent_id
end
class CreatePosts …Run Code Online (Sandbox Code Playgroud) 我想知道这是否可行.
我希望根据表1的数据加入2个表.示例表1包含列食物,其数据为"热狗".
我有一张叫热狗的桌子.
是否可以像JOIN一样进行JOIN.
SELECT * FROM table1 t join t.food on id = foodid
Run Code Online (Sandbox Code Playgroud)
我知道它不起作用,但它甚至可行,是否有一个工作周围?
提前致谢.
在一个表中使用一组外键的技术的名称是什么,其中除了一个外,其他所有外键都是NULL?
换句话说,每行需要一个外键到n个不同的可能表中的一个(并且只有一个),因此您实际上拥有所有必需的外键,但除了一个之外的所有外键都是NULL.
(Django的用户可能会认为这是使用通用外键的替代方法)
我的一位同事创建了一个类似于以下内容的架构。这是一个简化的模式,仅包含解决此问题所需的部分。
系统规则如下:
该架构为:
Department
----------
DepartmentID (PK) int NOT NULL
DepartmentName varchar(50) NOT NULL
Division
--------
DivisionID (PK) int NOT NULL
DepartmentID (FK) int NOT NULL
DivisonName varchar(50) NOT NULL
Article
-------
ArticleID (PK) int NOT NULL
UniqueID int NOT NULL
ArticleName varchar(50) NOT NULL
Run Code Online (Sandbox Code Playgroud)
他使用一个假想规则(由于缺乏更好的术语)定义了架构,所有DepartmentID都在1到100之间,所有DivisionID都在101到200之间。他指出,查询Article表时,您将知道是否唯一ID来自部门表或部门表,具体取决于其所属的范围。
我认为这是一个糟糕的设计,并提出了以下替代方案:
Department
----------
DepartmentID (PK) int NOT NULL
ParentDepartmentID (FK) int NULL /* Self-referencing foreign key. Divisions have parent departments. */
DepartmentName varchar(50) NOT NULL
Article
-------
ArticleID (PK) int NOT …Run Code Online (Sandbox Code Playgroud) 首先让我说我使用的是MySQL(不是事务性的),并且无法更改.此外,为简洁明了,我在这里简化了表格.
在这个例子中,'Lesson'由它的内部属性和一个外部属性组成,它有自己的属性'Readings'.'Readings'拥有自己的密钥依赖属性和三个不同的外部属性(阅读源).
我想避免在这里产生的多态关联,但我无法绕过它.在此示例中,'Reading'表中的'sourceId'将包含三个表"ExternalURL","InternalURL"和"Book"之一的id.此外,字段"polytable"将包含上述"id"来自的表名.
有人可以花一点时间来解释如何解决这种维护RI的问题,还是为了效率而应该留下它?
感谢您的时间和考虑,
蒂姆
-------------
| ExternalURL |
-------------
| id |
| badlink |
| url |
| |
| |
-------------
|
|
|
/ \
------------ ------------- -------------
| Lesson |-------<| Reading |>-------| InternalURL |
------------ ------------- -------------
| id | | id | | id |
| label | | lessonId | | url |
| summary | | sourceId | | |
| lessonOrder| | polytable | | |
| active | | …Run Code Online (Sandbox Code Playgroud) 当前的Ecto文档http://hexdocs.pm/ecto/Ecto.Schema.html仅解释了如何构建一种belongs_to多态关联,当多态Comment可以同时属于Task和Post.但相反的方向呢?
例如有一种Listing可以具有四种类型的属性的一个:Room,Apartment,Vila或Office.
考虑到一比一的关系,因为上面的例子那岂不是应该有rooms_listings,apartments_listings,vila_listings和office_listings,这是不可能的,因为这将导致所有相关联的其他表的复制listings.
问题是如何模拟这种关系?
我有以下实体:
public class Notification
{
public int Id { get; set; }
public string Title { get; set; }
public Guid RefId { get; set; }
public Object Ref { get; set; } // << The navigation property: Sometime its type is Poll and sometime is Test, maybe I add other types too
public NotifTypes Type { get; set; }
}
public enum NotifTypes
{
Poll=1,
Test=2,
// Other NotifTypes here
}
//-------------------------------------------------------------------
public class Test
{
public int Id …Run Code Online (Sandbox Code Playgroud) database ×4
mysql ×3
foreign-keys ×2
postgresql ×2
c# ×1
code-first ×1
ecto ×1
elixir ×1
join ×1
orm ×1