【问题标题】:Relational Database implementation关系数据库实现
【发布时间】:2013-04-18 17:41:24
【问题描述】:

不确定最好的实现是什么。我有两种不同类型的属性要跟踪故障。我希望能够在特定属性的显示页面上显示故障,然后在故障索引页面上查看所有故障。

最好有多个与每个属性相关的故障表,还是每个属性链接到一个故障表?如果将故障表中的多个空白 id 属性放在一起,我会担心它们。但如果它们被分开,我担心在视图中显示它们。我用 Rails 实现了这个。

一个故障表

Cars                   Trucks                Faults
-----------            ----------           -----------
car_id                 truck_id              fault_id
attribute_1            attribute_1           car_id
                                             truck_id
                                             fault description

两个故障表(每个属性一个)

Cars                   Trucks                car_Faults              truck_faults
-----------            ----------           -----------              -----------------
car_id                 truck_id              car_fault_id            truck_fault_id
attribute_1            attribute_1           car_id                  truck_id  
                                             fault description       fault description

【问题讨论】:

    标签: ruby-on-rails database model-view-controller database-design


    【解决方案1】:

    如果您希望能够同时显示所有故障并且还能够显示每个属性的故障,我认为这样的解决方案可能就是您正在寻找的解决方案

    Vehicles                Faults                      Types
    -----------            -----------                 ---------
    vehicle_id             fault_id                    vehicle_type
    vehicle_type(FK)       vehicle_id(FK)                  
    attribute_1            vehicle_type(FK)
                           fault_description
    

    然后在Types 中有一个条目,一个用于Car,一个用于Truck

    编辑:经过进一步思考,我意识到 Faults 中的 vehicle_type 是不必要的,因为要获得 Car 错误,您可以使用:

    SELECT fault_id AS F FROM Faults WHERE F.vehicle_id IN
      SELECT vehicle_id FROM Vehicles AS V WHERE V.vehicle_type IN
        SELECT vehicle_type FROM Types WHERE vehicle_type = 'Car'
    

    【讨论】:

      【解决方案2】:

      您可以使用与现有模型的多态关联,或使用单表继承将汽车和卡车组合成一个类。


      多态关联如下所示:

      Cars                   Trucks                Faults
      -----------            ----------           -----------
      id                     id                    id
      attribute_1            attribute_1           faultable_id
                                                   faultable_type
                                                   fault description
      

      您必须将faultable_id (int) 和faultible_type (string) 列添加到Fault。模型将如下所示:

      def Car < ActiveRecord::Base
        has_many :faults, :as => :faultable
      end
      
      def Truck < ActiveRecord::Base
        has_many :faults, :as => :faultable
      end
      
      def Fault < ActiveRecord::Base
        belongs_to :faultable, :polymorphic => true
      end
      

      允许您这样做:

      @car.fault
      # => returns car's fault
      
      @fault.faultible
      # => returns car or truck
      

      单表继承 (STI) 如下所示:

      Vehicle                Faults
      -----------            ---------- 
      id                     id   
      type                   vehicle_id
      attribute_1            fault description
      

      这有点难以理解,但CarTruck 都会从Vehicle 超类继承错误。这允许您在仅使用一个数据库表(单个表继承)的同时将汽车和卡车与故障相关联。

      汽车和卡车将存储为车辆记录,并共享共同属性。这非常适合具有几乎相同属性的模型,例如“颜色”或“品牌”。请记住,未使用的属性(卡车对象中的汽车属性)将为零。如果您正在处理许多不可互换的属性(因此有许多 nil),最好使用多态关联。

      型号:

      def Vehicle < ActiveRecord::Base
        has_many :faults
      end
      
      def Car < Vehicle
      end
      
      def Truck < Vehicle
      end
      
      def Fault < ActiveRecord::Base
        belongs_to :vehicle
      end
      

      你可以这样做:

      @truck.fault
      # => returns truck's fault
      
      @fault.vehicle
      # => returns either a Car or Truck object, depending on the type
      

      使用 STI 有一些注意事项:

      • 您必须实例化一个子类(汽车或卡车); 从不实例化超类(即Vehicle.new)。不要触摸Vehicletype 属性。 Rails 会自动处理它。

      • 没有收集类方法,所以像Truck.faults(所有卡车的故障)这样的东西不起作用。

      【讨论】:

      • 还没有机会玩它,但看起来多态可以工作。我假设您可以通过将 :as => faultable 添加到所有需要正确关联的表来与 2 个以上的模型建立关联?上表是我使用的实际模型的简化表示
      • 正确。您可以在多态关联中拥有任意数量的模型,前提是它们都使用:as =&gt; :faultable 接口。
      • 我可以让你检查一下这个设计实现,看看它是否有意义/有效吗?我正在努力确保我从一开始就正确设置了这个设置,而不是建立一个糟糕的设计并在访问数据的过程中遇到问题。
      猜你喜欢
      • 2019-11-06
      • 2010-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 2010-09-13
      相关资源
      最近更新 更多