目前我的原始数据格式如下
---------------------------------------------------------------------
| User Number charges cost account# |
| John Smith 555-555-5555 Rental $700 12345 |
| John Smith 555-555-5555 Phone $100 12345 |
| Mike Jones 444-444-4444 Late Pay $50 98765 |
| John Smith 555-555-5555 Surcharge $100 12345 |
----------------------------------------------------------------------
这只是我把它放在一起的一个例子,但是在原始数据没有适当分组的方面,设置几乎相同。正如您可以看到细分列表John Smith及其信息,然后跳转到Mike Jones,然后回到John Smith,在user
,number
和account#
中创建了许多重复的条目柱。我拥有的真实数据文件是以这种方式设置的,但由数千行和10-20列组成。我一直试图找到一种方法来打破用户名和数字到一个单独的表中,我可以在其中创建与文件其余部分的关系,以帮助优化表。我意识到如果我手动输入每个条目,我就可以这样做,但这显然会占用很多时间,并且每次需要将其中一个数据文件上传到数据库时,这是不可行的。
最初我以为我只会创建一个用户名表来保存用户的名称和号码,对于每个用户,我会有一个自动递增的键,它将链接到表的其余部分。我遇到的问题是,对于像John Smith
这样的人,我会有一个看起来像这样的表:
--------------------------------------
| ID User Number |
| 1 John Smith 555-555-5555 |
| 2 Mike Jones 444-444-4444 |
---------------------------------------
我必须进入并在主表中为其名称的每个实例输入1
的外键:
-----------------------------------------------------
| ID Charges Cost account# |
| 1 Rental $700 12345 |
| 1 Phone $100 12345 |
| 2 Late Pay $50 98765 |
| 1 Surcharge $100 12345 |
--------------------------------------------------------
有没有办法在没有进入的情况下连接表格,并且每次收费表都有与约翰史密斯有关的东西时手动输入1
?
答案 0 :(得分:1)
您可以使用第三个表作为两者之间的链接。
使用你的例子,我考虑做类似的事情:
USER_TABLE
-----------------------------------------
| User Number acccount# |
| John Smith 555-555-5555 12345 |
| Mike Jones 444-444-4444 98765 |
------------------------------------------
order_table
------------------------------------------
| Order# Charges Cost |
| 1 Rental $700 |
| 2 Phone $100 |
| 3 Late Pay $50 |
| 4 Surcharge $100 |
------------------------------------------
user_orders_table
----------------------------
| account# order# |
| 12345 1 |
| 12345 2 |
| 98765 3 |
| 12345 4 |
----------------------------
订单#将由您的数据库自动递增。假设帐号是设计上唯一的,因此它可以作为user_table的主键。然后user_orders_table将是存储两个表之间链接的方法。
<强>更新强>
如果需要保留用户表的数据库管理标识符,则可以按如下方式调整示例:
USER_TABLE
-------------------------------------------------
| user_uid User Number acccount# |
| 1 John Smith 555-555-5555 12345 |
| 2 Mike Jones 444-444-4444 98765 |
--------------------------------------------------
order_table
------------------------------------------
| Order# Charges Cost |
| 1 Rental $700 |
| 2 Phone $100 |
| 3 Late Pay $50 |
| 4 Surcharge $100 |
------------------------------------------
user_orders_table
----------------------------
| user_id order# |
| 1 1 |
| 1 2 |
| 2 3 |
| 1 4 |
----------------------------
更新2
实现此目的的一种方法是使用procedure进行插入。使用存储过程的目标是实现注释中提到的步骤。
插入新订单
1. Check for user
1.a User exists, get their id
1.b User does not exits. Insert them and get their id.
2. Create new order record
3. Create user_orders record
请将此视为伪代码。
我无法访问MySQL数据库来测试这个......而且它只是想提供一个更详细的理论示例来说明如何实现。
DELIMITER //
CREATE PROCEDURE InsertOrder(
IN
p_user_name VARCHAR(50),
p_user_phone_number VARCHAR(13),
p_user_account_number VARCHAR(50),
p_order_charges VARCHAR(15),
p_order_cost MEDINT
)
BEGIN
//check for the user in the database. If they exist, get their id. If they don't, insert them
IF EXISTS (SELECT user_uid FROM USERS_TABLE WHERE user_name = p_user_name) //user exists... get their uid
r_user_uid = user_uid;
ELSE //user doesn't exist... create the sucker
INSERT INTO USER_TABLE (user_name, user_phone_number, user_account_number)
VAULES(p_user_name, p_user_phone_number, p_user_account_number); //assuming that user_uid is an auto_incremented value
r_user_uid = SELECT user_uid FROM USERS_TABLE WHERE user_name = p_user_name;
END IF
//insert your order information NOTE: could be prudent to check if the order exists already... but we will assume it doesn't for the sake of the pseudo code example.
INSERT INTO ORDER_TABLE (order_charges, order_cost)
VALUES (p_order_charges, p_order_cost); --assuming that order number is an auto_incremented value.
r_order_id = SELECT max(order_number) FROM ORDER_TABLE //assumes the latest entry is the correct one... may not be the most robust way to do this... depending on how this is to be used overall.
//Now create the user_orders record
INSERT INTO USER_ORDERS_TABLE (user_id, order_number) VALUES (r_user_uid, r_order_number);
END //
DELIMITER ;
请注意: 在其他评论中,在原始问题之后,您提到数据集中的用户没有真正的唯一数据。对于您来说,这对于实现这样的解决方案来说可能是一个真正的问题。要拥有一个良好的用户表,您需要一种方法使数据本身是唯一的。仅依靠数据库生成的标识符并不理想......不推荐使用。例如,如果要输入
User Number account#
John Doe 555-555-5555 12345
John Doe 555-444-3333 12345
John Doe 555-555-5555 12345
这是两个具有相同名称的不同用户的列表;或者是同一个用户,他们的电话号码是谁?为了创建一个良好的用户表,您必须能够从要插入的数据中确定这一点。因此,需要一些额外的部分来唯一地识别用户。
您可能在剩余的列中包含其他数据,以帮助您完成此任务...但如果不是......那么创建用户表可能不是规范化数据的最佳解决方案。
我希望这会有所帮助。
答案 1 :(得分:1)
首先,您似乎不需要创建Id列,因为传入的数据文件已经具有帐户#字段,这可能为客户提供所需的唯一密钥(否则如何区分两个不同的约翰史密斯在那个文件?)。
所以你需要一个表(称之为Customer或者其他东西),有两列(如果有其他的cusomer数据要保留更多),一列叫做AccountNum,另一列叫User。使用您在上面显示的数据,它将如下所示:
AccountNum User
12345 John Smith
98765 Mike Jones
和第二张表(费用表):
AccountNum Charges Cost Date
12345 Rental $700 2014-10-23
12345 Phone $100 2014-10-25
98765 Late Pay $50 2014-10-22
12345 Surcharge $100 2014-10-23
然后,每次收到新数据文件时,逐行读取,解析该行以提取帐户#值,然后查看Customer表以检查AccountNum列中是否存在该值。如果是,只需在Charges表中创建一个新记录,使用第二个表中AccountNum列的帐号。如果帐户#值不在Customer表中,则它是新客户,您必须在将该数据添加到Charges表之前在该表中创建新记录。
据推测,这些指控也有日期字段?这将区分同一客户的相同金额的两项费用。我希望这能很好地解释。