How to design one-to-many relationship tables considering update operation? - mysql

I may appoint some specific receivers when new a notice. So I design one-to-many tables named notice and receiver:
mysql> select * from notice;
+----+-------+
| id | title |
+----+-------+
| 1 | demo |
+----+-------+
mysql> select * from receiver;
+----+-----------+--------+
| id | notice_id | name |
+----+-----------+--------+
| 1 | 1 | calvin |
| 2 | 1 | john |
+----+-----------+--------+
When I update the notice, the receivers might be updated too(Assuming the receivers should be updated to calvin and Jack). My current solution is deleting all receivers related to the notice and inserting the new ones. Is there any better and higher-performance solution? I can redesign the tables if it's necessary.

Related

How to handle friend request accept logic in database?

I am working on a simple social app and have a user_friend table which has both the user_id and friend_id as its composite keys. In the front end, the current user can look at other people's profiles and then click on add friend button which updates the user_friend table. For example, user with id 100 can view user with id 9's and 15's profiles and click on add button and then the user_friend table gets updated as
user_id: 100, friend_id 9
and
user_id: 100, friend_id 15
What is the best approach to handling such request? I was thinking creating a new table called request_table which has requester column which has the id for the user, accepter column which has the id for the friend and status column with accepted and pending. So, when requester clicks add friend button, the status gets updated to accepted which then updates the user_friend table to to reflect the change (by adding a new row user_id: 9, friend_id 100 in the above example).
Please advice if there are cleaner or better ways to do this.
I would make it much simpler than you are thinking .. Your current table looks like:
+--------------------------------+
| user_id | friend_id |
+--------------+-=---------------+
| 100 | 15 |
+--------------+-----------------+
| 100 | 9 |
+--------------+-----------------+
Add two columns .. requested and accepted:
+--------------------------------+-----------------+----------------+
| user_id | friend_id | requested | accepted |
+--------------+-=---------------+-----------------+----------------+
| 100 | 15 | 1 | 0 |
+--------------+-----------------+-----------------+----------------+
| 100 | 9 | 1 | 1 |
+--------------+-----------------+-----------------+----------------+
Although one could ASSUME that if the entry is in the table requested will always be 1 -- So really you only need to add the accepted column .. But you get the basic idea/principle.
NOTE if you need more statuses than just "accepted" like -- Say "blocked" or "suspended" etc etc you can create a third table and use the in a relational way.
+-----------------------------------------------------------------+
| user_firends (uf_id for indexing FASTER) |
+--------------------------------+-----------------+--------------+
| uf_id | user_id | friend_id | status |
+--------------+-=---------------+-----------------+--------------+
| 1 | 100 | 9 | 1 |
+--------------+-----------------+-----------------+--------------+
| 2 | 100 | 15 | 2 |
+--------------+-----------------+-----------------+--------------+
+---------------------------------------+
| statuses_table |
+------------------+--------------------+
| status_id | status |
+------------------+--------------------+
| 1 | requested |
+------------------+--------------------+
| 2 | accepted |
+------------------+--------------------+
| 3 | rejected |
+------------------+--------------------+
| 4 | blocked |
+------------------+--------------------+
many (users) to many (friends) with a users_friends "pivot" table AND
many (friends) to single (staus) with a direct insert of status in the column

Mysql: Change set column on update condition?

I'm trying to figure out the best way to update one of two fields in a table. I have a personrelationship table and it links two people and I would like to have each person be able to set the relationship type on their end.
PersonRelationship Table
id int
user1_id int
user2_id int
user1_reltype /* boss, manager, etc */
user2_reltype
Depending on whether the current user is either user1_id or user2_id in the table, I need to update the user_reltype accordingly. So basically if current userid is in the user1_id field then update user1_reltype otherwise update the user2_reltype.
Since you want each user to be able to independently manage their half of the relationship, you can simplify your table structure
--------------------------------------
| initiator_id | reltype | target_id |
When a person with ID 5 (the 'initiator') marks person with ID 9 (the 'target') as a friend, the table will contain:
---------------------------------------
| initiator_id | reltype | target_id |
+--------------+----------+-----------+
| 5 | 'friend' | 9 |
If person 9 later initiates a 'boss' connection with person 5, the entry can be created without interfering with the row previously created by person 5:
--------------------------------------
| initiator_id | reltype | target_id |
+--------------+---------+_----------+
| 9 | 'boss' | 5 |
This approach will make your table easy to read and your queries easy to write.
Extra:
If you do not already have it, consider creating another table to track relationship types ('reltype'):
-----------------
| id | type |
+----+----------+
| 1 | 'friend' |
| 2 | 'boss' |
and replace the string reltype's in the relationship table with foreign keys.
---------------------------------------
| initiator_id | reltype | target_id |
+--------------+----------+-----------+
| 5 | 1 | 9 |
| 9 | 2 | 5 |

Application specific MySQL table Structure

I have a question about my DB table structure. I want to know if i'm on the right track or if I have missed a good alternative. Here is the case:
To make it easy to read, I haven't pasted the full contents as my question is only about the structure.
2 tables:
1: id (AI), task
2: id, name, task
Table 1 presents dynamic check-boxes which can be altered by an admin panel so the contents would be like this
1 task1
2 task2
5 task5
(3 & 4 are missing cause the administrator deleted those records).
In table number two are the people who should do the tasks from table 1. And the goal is that the tasks wich are not checked will be displayed.
So the contents of table 2 would be:
1 Name1 1,5
2 Name2 1,2
3 Name3 1,2,5
The numbers in table 2 represent the checked boxes from table 1. So with a query i can compare the numbers from table 2 with the id's from table 1 and display the missing ids as "todo".
In my opinion this looks very overdone, and there must be an easier way to create dynamic options which can be compared and stored as a todo.
Suggestions are welcome!
I suggest you to use basic structure for many-to-many relationship:
tasks users user_tasks
+----+-----------+ +----+-------+ +---------+---------+
| id | name | | id | name | | user_id | task_id |
+----+-----------+ +----+-------+ +---------+---------+
| 1 | Buy milk | | 1 | John | | 1 | 2 |
| 2 | Get drunk | | 2 | Tim | | 3 | 2 |
| 3 | Have fun | | 3 | Steve | | 2 | 4 |
| 4 | Go home | +----+-------+ | 3 | 4 |
+----+-----------+ +---------+---------+
And you can fetch unassigned tasks using following query:
SELECT
tasks.*
FROM
tasks
LEFT JOIN
user_tasks
ON (tasks.id = user_tasks.task_id)
WHERE
user_tasks.user_id IS NULL
You also can fetch users who have no assigned tasks:
SELECT
users.*
FROM
users
LEFT JOIN
user_tasks
ON (users.id = user_tasks.user_id)
WHERE
user_tasks.user_id IS NULL
Hope this will help you.

MySQL best approach for db normalising, relationships and foreign keys

There is an username/password verification step first then the database has following structure
^ is primary key
* uses foreign key
1.StudentDetails table
===========================================================================
ID^| Username | Password | Email | Address * | Website |Comments
====+============+==========+=============+===========+=========+==========
1 | xxxxxxxxxx | xxxxxxx | xx#xxx.xxx | 1 | http:// | text
2.Submissions table
===========================================================================================
ID^|Username*|SubmitDate|SelectedCourse*|Price*|Promotion*|SubmitComments|SubmitStatus*
===+=========+==========+===============+======+==========+==============+=================
1 |xxxxxxxxx|2013-7-12 | int | int | int | text | int
3.SubmitComplete table
==================================================
ID^| Username * | SelectionDate | SubmitStatus *
====+============+===============+================
1 | xxxxxxxxxx | 2013-08-01 | int
Now I'm having an issue entering the address, when i try to enter the student details it won't accept until there is an address field, how best to tackle that?
When i do an left join selecting certain fields from StudentDetails and certain fields from Addresses, addresses don't show.
Im a mysql noob, so i'd like some guidance to see if the normalising and structure has been done correctly, or could it be done better, here is the fiddle i couldn't get it to work properly, kept getting errors on the lines where i added the foreign keys, even though the building of the schema worked well on my machine.
The fiddle console says error on line 2 but it looks to me it's actually on line 76.
If there's anything i was unclear on, pls let me know.
Thanks
Ok let me explain you how it would be. I made an example with two tables that you can see below.
Then you can create your query.
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| addresses |
| students |
+----------------+
2 rows in set (0.00 sec)
mysql> select * from students;
+----+----------+-----------+
| id | name | last_name |
+----+----------+-----------+
| 1 | jhon | smith |
| 2 | anderson | neo |
| 3 | trinity | jackson |
+----+----------+-----------+
3 rows in set (0.00 sec)
mysql> select * from addresses;
+----+-----------------+---------+
| id | address | student |
+----+-----------------+---------+
| 1 | Av 1 2nd Street | 1 |
| 2 | Av 3 4 Street | 2 |
| 3 | St 23 7 Av | 3 |
+----+-----------------+---------+
3 rows in set (0.00 sec)
mysql> select s.name,s.last_name,a.address from students s join addresses a on a.student=s.id;
+----------+-----------+-----------------+
| name | last_name | address |
+----------+-----------+-----------------+
| jhon | smith | Av 1 2nd Street |
| anderson | neo | Av 3 4 Street |
| trinity | jackson | St 23 7 Av |
+----------+-----------+-----------------+
3 rows in set (0.00 sec)
option 1:
enter the adress data first, and use that id when createing the row in StudentDetails
option 2:
change the field StudentDetails.Address so its allow NULL valus, enter the StudentDetails, then the adress, and then update the StudentDetails.Address
It's better to use foreign keys in number format So the Username should be the id of the StudentDetails table.
Can you put the SQL Query that you had tried to run?

Data Entry Tracking (Database Design)

I have developed a website (PHP) that allow staffs to add records on to our system.
Staffs will be adding thousands of records into our database.
I need a way to keep track of what record have been done and the process/status of record.
Here a number of Teams I could think of:
Data Entry Team
Proof Reading Team
Admin Team
When staff (Data Entry Team) completed a record - he/she will then click on the Complete button. Then somehow it should asssign to 'Proof Reading Team' automatically.
A record need to be checked twice from a Proof Reading Team. If StaffB finish proof reading then another member from Proof Reading Team need to check it again.
When Proof reading is done, Admin Team will then assign "Record Completed"
In a few months later record might need to be updated (spelling mistake, price change, etc) - Admin might to assign record to Data entry team.
Is this good data entry management solution? How do I put this into Database Design perspective?
Here what I tried:
mysql> select * from records;
+----+------------+----------------------+
| id | name | address |
+----+------------+----------------------+
| 1 | Bill Gates | Text 1 Text Text 1 |
| 2 | Jobs Steve | Text 2 Text 2 Text 2 |
+----+------------+----------------------+
mysql> select * from staffs;
+----+-----------+-----------+---------------+
| id | username | password | group |
+----+-----------+-----------+---------------+
| 1 | admin1 | admin1 | admin |
| 2 | DEntryA | DEntryA | data_entry |
| 3 | DEntryB | DEntryB | data_entry |
| 4 | PReadingA | PReadingA | proof_reading |
| 5 | PReadingB | PReadingB | proof_reading |
+----+-----------+-----------+---------------+
mysql> select * from data_entry;
+----+------------+-----------+------------------------+
| id | records_id | staffs_id | record_status |
+----+------------+-----------+------------------------+
| 1 | 2 | 3 | data_entry_processiing |
| 2 | 2 | 3 | data_entry_completed |
| 3 | 2 | 4 | proof_read_processing |
| 4 | 2 | 4 | proof_read_completed |
| 5 | 2 | 5 | proof_read_processing |
| 6 | 2 | 5 | proof_read_completed |
+----+------------+-----------+------------------------+
Is there alternative better solution of database design?
i think design it's well done. but may be you want to separate group into groups table, and record_status into status table. If you're storing a lot of records you would store a lot of useless information, at least create an enum type for record_status field and group field
table: groups
id - name 1 - admin 2 - data_entry 3 - proof_reading
...
table: status
id - name 1 - data_entry_processing ...
and if you want the users to be in different groups at a time, you could create users_group table
table: user_groups
group_id - user_id 1 - 1 2 - 1 1 - 4 3 -
4 4 - 4 ....
Hope this helps