Normalize contacts in MySQL database - mysql

I am trying to create a chat application with a login. I am using MySQL database for storing the user data. My table is called userData. It contains:
userID*
userPass
firstname
surname
role
contacts
OK, so this system is for staff and students and users are able to add contacts to their list. I am struggling to structure my database to store the contacts efficiently. Basically I am not sure how to normalize with the contacts column.
For example...
userID* userPass firstname surname role contacts
1234 2012 Sponge Bob Student 1345
1234 2012 Sponge Bob Student 3421
1234 2012 Sponge Bob Student 1445
Would it be appropriate for me to create a table for each userID to store the contacts? I am making this in JAVA using a MySQL db. Would be grateful for any tips.

You should have two tables, one with user data and other with contacts. This can then be joined by using the shared identifier.
CREATE TABLE userData (userID int primary key, userPass varchar(32), firstname varchar(32), surname varchar(32), roleID int);
CREATE TABLE roles (roleID int primary key, rolename char(32));
CREATE TABLE contacts (userID int, contactID int);
I threw 'roles' in there as an example. You can then join these as necessary, e.g:
SELECT contacts.* FROM contacts
JOIN userData USING (userID)
WHERE userData.userID=1234;
Or to take if further and benefit from the normalization:
SELECT CONCAT(ud.firstName,' ',ud.surName),
CONCAT(cd.firstName,' ',cd.surName)
FROM contacts
JOIN userData AS cd on (cd.userID=contacts.contactID)
JOIN userData AS ud on (ud.userID=contacts.userID)
WHERE
contacts.userID=1234;

Related

Merging rows and updating related foreign key

I have a current users table. A distinct user is defined as when the email and phoneNumber together are unique. Currently the table looks like this:
And another table called giftee_info which has the foreign key on column userId to users.id:
The users table is going to be parsed out into 2 tables: users and user_metadata. Now a distinct user will be defined by the phoneNumber. So you can see in the data above, users with id's 4 and 5 are the same, and have to be merged.
The new users table will look like:
And the new user_metadata table will look like this:
Note how the 4th row has userId of 4, so users 4 and 5 have merged to one user.
And giftee_info will look like this:
See how the 3rd row in giftee_info contains userId 4, as the user with id 5 has been merged into one user.
The data I've provided is basic. In reality there are many rows, and a user with the same number may have 5 different email address (and so are currently treated as separate users in the current schema).
The part I'm having most trouble with is updating giftee_info. So any rows with userId's that have been merged down into one user need to be updated. How can I do this?
Since phonenumber can be NULL, I'm using externalid as the unique identifier below.
Start by creating the new users table from the distinct phone numbers in the old users table:
CREATE TABLE new_users (id INT PRIMARY KEY AUTO_INCREMENT, externalid VARCHAR(32), phonenumber VARCHAR(32))
SELECT DISTINCT NULL, externalid, phonenumber
FROM users
Then put all the emails into the user_metadata table, by joining the old and new users tables to get the emails along with the new user IDs.
CREATE TABLE user_metadata (id INT PRIMARY KEY AUTO_INCREMENT, userid INT, email VARCHAR(100), subscribe INT(1))
SELECT NULL, nu.id, u.email, 0
FROM new_users as nu
JOIN users AS u ON nu.externalid = u.externalid
Now you can update giftee_info by replacing the old user IDs with the new user IDs.
UPDATE giftee_info AS g
JOIN users as u ON g.userid = u.userid
JOIN new_users As nu ON nu.externalid = u.externalid
SET g.userid = nu.userid
Once this is all done you can rename the tables so new_users is now users.

mysql database how to store contact data

I want to fetch contacts from phone
and store into mysql database
I have:--
User table
id,userId, name, username, password
Contact table
id
userId(foreignkey(from user table))
contact_name
mobileNo(unique-primary key)
email(unique key)
Now problem is:
1)Suppose I am fetching sonia's contact list
where,
she has one contact:-
Name mobileNo email
Soma 5675675675 aaa#mail.com
another user preeti's contact list has:-
Name mobileNo email
sree 999999385 aaa#mail.com
and again another user lila's contact list has:-
Name mobileNo email
mona 5675675675 agawasti#mail.com
In my database
mobileNo and email is unique-primary key,
but for every user name/email/mobileNo may be different..how I can store and manage these data
for individual user??
I got one solution :-
1] User_info Table
id | UserId | name | username |password
2] Contacts Table
ContactId | Contact_Name | Contact_Phno |Contact_Email
3] User_Contact Table
UserId | ContactId
but Here, in Contacts table how can I manage to store sonia,preeti/lila's contact information? because the values are different.
You can have only one primary key per table, but maybe you defined a composite key (can't tell from the question)? I would suggest making 'id' a primary key and to add uniqueness constraints on the mobileNo and email. This choice also plays nicely with most of the web-frameworks you might be using.
ALTER TABLE `contact` ADD UNIQUE `unique_index`(`mobileNo`, `email`);
check your data type for phone number. May be it is integer and your phone number is over its limit..

MySql load file script and 2 tables

So I have 2 tables, one is an contact table like
ContactId BigInt PK
Name varchar
Phone varchar
Address varchar
and a second table Vendor
CompanyName varchar
ContactId BigIn FK
I want to load vendors into the tables such that
When I load vendors with a CSV it will put them in the contact table and load them into the vendor table
123423234, bob smith, 333-444-5555, 123 stree dr., CompanyOne
123123234, john doe, 444-333-2222, 423 SomeStreet st., Another Company
I kept the tables small and simple for the post, yes there is more but the key here is I need to use the ContactID from the contact table in the Vendor table. and I want to load them both from the same cvs. I know how to do this if it was just the one table but not sure with the 2 tables.
Thanks!
You may be able to do this with all SQL, or it might require/be easier with a scripting language like PHP. But here is the basic pseudo code idea.
CREATE an unnormalized table that your CSV file can fit into pretty directly (we'll call it tempTable). Then put the data from the CSV into there. (Pretty sure this will require some scripting).
Insert contact info into contact table:
INSERT INTO contact (name, phone, address) (SELECT DISTINCT name, phone, address FROM tempTable);
Add a contactID column to tempTable and update it with the IDs from the contacts table by JOINing:
UPDATE tempTable JOIN contact ON
tempTable.name = contact.name
AND tempTable.phone = contact.phone
AND tempTable.address = contact.address
SET tempTable.contactID = contact.contactID
Then INSERT into vendor much like the way we inserted in to contact:
INSERT INTO VENDOR (companyName, contactID) (SELECT company, contactID FROM tempTable);

Inserting data to table

currently I have three table: test, contact and staff
test
FirstName LastName
Contact
Contact_Id Contact_FirstName Contact_LastName
staff
Staff_ID Contact_Id
The Staff Id should be auto-increment, I need a script that go through all row in test table. If the FirstName and LastName Matches Contact_FirstName and Contact_LastName. Add Matched Contact_ID number to the Contact_Id thats in the Staff table.
INSERT INTO `staff` (`Contact_Id`)
SELECT c.`ContactId`
FROM `Contact` c
JOIN `Test` t ON c.`Contact_FirstName` = t.`FirstName` AND
c.`Contact_LastName` = t.`LastName`
First change the structure of Staff table by adding IDENTITY in CREATE statement if you want it to be auto-incremented.
CREATE TABLE Staff (StaffID INT IDENTITY, ContactID INT)
now try this to insert just contactID because IDENTITY allows you to skip that column, sql creates those IDs for you.
INSERT Staff SELECT Contact_ID FROM Contact c JOIN Test t ON c.Contact_FirstName=t.FirstName and c.Contact_LastName=t.LastName
this seems like it's checking contact names of Contact based on Contact names of Test.. but this should work if you pass name of person in place of t.FirstName and t.LastName

SQL insert one record with multiple relational data in one transaction

Say, I have a customer profile with many contacts. That means I will have separated contact table from customer table.
tbl_customer
CustomerId (PK, NOT NULL, UNIQUE, AUTO_INCREMENT)
CustomerName
Address
(etc)
tbl_contact
ContactId (PK, NOT NULL, UNIQUE, AUTO_INCREMENT)
CustomerId (FK REFERENCES tbl_customer(CustomerId), CONSTRAINT)
Contact Type
Contact Number
So now let say, a customer called John Leweinsky has 4 contacts.
ContactType1: Fax
ContactType2: Office Phone
ContactType3: Personal Phone
ContactType4: Personal Phone
Can this be done in one query transaction without knowing CustomerId?
Thanks for advance if you have answered this.
Try like this
START TRANSACTION;
insert into (feilds name) values(Values);
insert into tbl_contact(CustomerId ,ContactType,ContacNumber)
values((select max(CustomerId) from tbl_customer),'type1','Fax');
COMMIT;
Pass all other contacttype
Assuming the name is unique, you can do this as:
insert into tbl_contact(CustomerId, ContactType, ContactNumber)
select cust.CustomerId, c.ContactType, c.ContactNumber
from (select 'Fax' as ContactType, Faxnumber as ContactNumber union all
select 'Office', Officenumber union all
select 'PersonalPhone', PersonalPhone union all
select 'PersonalPhone', PersonalPhone
) c cross join
Customers cust
where cust.CustomerName = 'John Leweinsky';
If name is not unique, you need some way to disambiguate the customers.
No, the only way to properly add something to tbl_contact is with the CustomerId. You're Customer Name is not unique ( nor should it be ) so you have no way to link your contacts with John Leweinsky, unless this is just a toy example and you want to pretend that John Leweinsky is unique.
You can add the contacts without knowing the CustomerId ( in some database engines, PostgreSQL for exapmle ) but the won't be connected to John Leweinsky.