MySQL: how to do row-level security (like Oracle's Virtual Private Database)?

后端 未结 3 2234
梦毁少年i
梦毁少年i 2020-12-11 21:55

Say that I have vendors selling various products. So, at a basic level, I will have the following tables: vendor, product, vendor_product

相关标签:
3条回答
  • 2020-12-11 22:24

    This sounds to me that you want to normalize your data. What you have is a 1 (product) to many (vendors) relationship. That the relationship is 1:1 for most cases and only 1:n for some doesn't really matter I would say - in general terms it's still 1:n and therefor you should design your database this way. The basic layout would probably be this:

    Vendor Table
    VendorId    VendorName    OtherVendorRelatedInformation
    
    WidgetTable
    WidgetId    WidgetName    WidgetFlag     CreatorVendor   OtherWidgetInformation
    
    WidgetOwnerships
    VendorId    WidgetId      OwnershipStatus     OtherInformation
    

    Update: The question of who is allowed to do what is a business problem so you need to have all the rules laid out. In the above structure you can flag which vendor created the widget. And in the ownership you can flag what the status of the ownership is, for example

    • CreatorFullOwnership
    • SharedOwnership
    • ...

    You would have to make up the flags based on your business rules and then design the business logic and data access part accordingly.

    0 讨论(0)
  • 2020-12-11 22:29

    You already suggested a vendor, product and vendor_product mapping table. You want vendors to share the same product if they both want to use it, but you don't want duplicate products. Right?

    If so, then define a unique index/constraint on the natural key that identifies a product (product name?).

    If a vendor adds a product, and it doesn't exist, insert it into the product table, and map it to that vendor via the vendor_product table.

    If the product already exists, but is mapped to another vendor, do not insert anything into the product table, and add another mapping row mapping the new vendor to the existing product (so that now the product is mapped to two vendors).

    Finally, when a vendor removes a product, instead of actually removing it, just delete the vendor_product reference mapping the two. Finally, if no other vendors are still referencing a product, you can remove the product. Alternatively, you could run a script periodically that deletes all products that no longer have vendors referencing them.

    Finally, have a flag on the product table that says that you've reviewed the product, and then use something like this to query for products viewable by a given vendor (we'll say vendor id 7):

    select product.*
    from product
    left join vendor_map
    on vendor_map.product_id = product.product_id
    where vendor_map.vendor_id = 7
    or product.reviewed = 1;
    

    Finally, if a product is owned by multiple vendors, then you can either disallow edits or perhaps "split" the single product into a new unique product when one of the owning vendors tries to edit it, and allow them to edit their own copy of the product. They would likely need to modify the product name though, unless you come up with some other natural key to base your unique constraint on.

    0 讨论(0)
  • 2020-12-11 22:50

    Mysql doesn't natively support row level security on tables. However, you can sort of implement it with views. So, just create a view on your table that exposes only the rows you want a given client to see. Then, only provide that client access to those views, and not the underlying tables.

    See http://www.sqlmaestro.com/resources/all/row_level_security_mysql/

    0 讨论(0)
提交回复
热议问题