简体   繁体   English

mysql-许多表到一个表-多个条目

[英]mysql - Many tables to one table - multiple entries

I have a system which has (for the sake of a simple example) tables consisting of Customers, Vendors, Products, Sales, etc. Total 24 tables at present. 我有一个系统(具有一个简单的示例),该表由客户,供应商,产品,销售等组成。目前共有24个表。

I want to add the ability to have multiple notes for each record in these tables. 我想增加对这些表中的每个记录具有多个注释的功能。 Eg, Each Customers record could have 0 to many notes, each Vendor record could have 0 to many notes, etc. 例如,每个客户记录可能有0到很多便笺,每个供应商记录可能有0到很多便笺,依此类推。

My thinking is that I would like to have one "Notes" table, indexed by a Noteid and Date/time stamp. 我的想法是,我想要一个“ Notes”表,该表由Noteid和日期/时间戳索引。 The actual note data would be a varchar(255). 实际的注释数据将是varchar(255)。

I am looking for a creative way to bi-directionally tie the source tables to the Notes table. 我正在寻找一种将源表与Notes表双向绑定的创新方法。 The idea of having 24 foreign key type cross reference tables or 24 Notes tables doesn't really grab me. 拥有24个外键类型交叉引用表或24个Notes表的想法并没有真正吸引我。

Programming is being done in PHP with Apache server. 编程是通过PHP与Apache服务器一起完成的。 Database is mysql/InnoDB. 数据库是mysql / InnoDB。

Open to creative ideas. 接受创意。

Thanks 谢谢

Ralph 拉尔夫

I would sugges a table like this 我建议这样的桌子

note_id  :  int autoincrement primary
type_id  :  int, foreign key from f Customers, Vendors, Products etc 
type     :  varchar, code indicating the type, like Vendors, VENDORS or just V 
note     :  varchar, the actual node


CREATE TABLE IF NOT EXISTS `notes` (
  `note_id` int(11) NOT NULL AUTO_INCREMENT,
  `type_id` int(11) NOT NULL,
  `type` varchar(20) CHARACTER SET utf8 NOT NULL,
  `note` varchar(255) CHARACTER SET utf8 NOT NULL,
  PRIMARY KEY (`note_id`)
) 

With a setup like that you can have multiple notes for each type, like Vendors, and also hold notes for multiple types. 通过这样的设置,您可以为每种类型(如供应商)提供多个注释,也可以保存多种类型的注释。

data sample 数据样本

note_id     type_id     type          note
--------------------------------------------------------------------
1           45          Vendors       a note 
2           45          Vendors       another note
3           3           Customers     a note for customer #3
4           67          Products      a note for product #67

SQL sample SQL样本

select note from notes where type="Vendors" and type_id=45

To reduce table size, I would prefer aliases for the types, like V , P , C and so on. 为了减少表的大小,我希望为VPC等类型使用别名。

Don't do a "universal" table, eg 不要做一个“通用”表,例如

id, source_table, source_record_id, note_text id,source_table,source_record_id,note_text

might sound good in practice, but you can NOT join this table against your others without writing dynamic SQL. 在实践中可能听起来不错,但是如果不编写动态SQL,就无法与其他表连接该表。

It's far better to simply add a dedicated notes field to every table. 最好在每个表中简单地添加一个专用的注释字段。 This eliminates any need for dynamic sql, and the extra space usage will be minimal if you use varchar/text fields, since those aren't stored in-table anyways. 这消除了对动态sql的任何需求,并且如果您使用varchar / text字段,那么额外的空间使用将是最小的,因为它们始终不会存储在表中。

I've done a structure like this before where I used a format like this: 在使用如下格式之前,我已经完成了这样的结构:

id (int)
target_type (enum/varchar)
target_id (int)
note (text)

Each data element just has to query for it's own type then, so for your customer object you would query for notes attached to it like this 然后,每个数据元素仅需要查询其自身的类型,因此对于客户对象,您将需要查询附加到它的注释,如下所示

SELECT * FROM notes where target_type='customer' AND target_id=$this->id

You can also link target_type to the actual class, so that you write to the database using get_class($this) to fill out target type, in which case a single function inside of the Note class could take in any other object type you have. 您还可以将target_type链接到实际的类,以便使用get_class($ this)填写目标类型来写入数据库,在这种情况下,Note类内部的单个函数可以采用您拥有的任何其他对象类型。

In my opinion, there isn't a clean solution for this. 我认为,对此没有一个干净的解决方案。

option 1: Master entity table 选项1:主实体表

Every (relevant) row of every (relevant) table has a master entry inside a table (let's call it entities_tbl . The ids of each derived table isn't an autoincrement but it's a foreign key referencing the master table. 每一个(相关)表中的每一(相关)行有一个表内的主入口(姑且称之为entities_tbl 。每个派生表的id是不是自动增量,但它是一个外键引用的主表。

Now you can easily link the notes table with the master entity id. 现在,您可以轻松地将注释表与主实体ID链接起来。

PRO: It's an object oriented idea. PRO:这是一个面向对象的想法。 Like a base "Object" class which is the father of every other class. 就像基类“ Object”一样,它是所有其他类的父类。 Also, each entity has an unique id across the database. 此外,每个实体在数据库中都有唯一的ID。

CON: It's a mess. 缺点:很烂。 Every entity ID is scattered among (at least) two tables. 每个实体ID散布在(至少)两个表之间。 You'd need JOINs every single time, and the master entity table will be HUGE (it will contain the same number of rows as the sum of every other child table, combined) 您每次都需要JOIN,并且主实体表将非常庞大(它将包含与其他所有子表的总和相同的行数)

option 2: meta-attributes 选项2:元属性

inside the notes table, the primary key would contain an autoincrement, the entity_id and item_table_name. 在notes表中,主键将包含一个自动增量,entity_id和item_table_name。 This way you can easily extract the notes of any entity from any table. 这样,您可以轻松地从任何表中提取任何实体的注释。

PRO: Easy to write, easy to populate CON: It needs meta-values to extract real values. PRO:易于编写,易于填充CON:它需要元值来提取实值。 No foreign keys to grant referential integrity, messy and sloppy joins, table names as where conditions. 没有外键可以授予参照完整性,混乱和草率的连接,将表名作为条件。

option 3: database denormalization 选项3:数据库非规范化

(sigh, I've never considered to ever give this suggestion) Add a column inside each table where you need notes. (遗憾的是,我从未考虑过给出此建议)在每个需要注释的表中添加一列。 Store the notes as json encoded strings. 将注释存储为json编码的字符串。 (this means to denormalize a database because you will introduce non-atomic values) (这意味着要对数据库进行非规范化,因为您将引入非原子值)

PRO: easy and fast to write, uses some form of standard even for future database users, the notes are centralized and easily accessible from each entity CON: the database isn't normalized, poor search and comparison between notes PRO:编写简便,快速,甚至为将来的数据库用户使用某种形式的标准,注释集中并且可以从每个实体轻松访问CON:数据库没有规范化,注释之间的搜索和比较差

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM