How to Implement Message feature in website - mysql

I have a table
____________________________________________________________
| Message |
|___________________________________________________________|
| Sender | Message | Receiver | message_id |
| John | How Are You?| Will | 1 |
|_________|_____________|___________________|_______________|
In Will computer I am showing as follows
Message By:John
Message:How Are You?
Now Suppose John Deleted this message But i can't remove the record because Will has not yet deleted.Therefore I am running a update query
Update Message Set Sender='' where message_id=1;
But after doing that in will computer message changes as follows
Message By: //Because i have changed sender to null
Message:How Are You?
Now how can i overcome this error of not getting desired output

Just maintain two more column boolean is_deleted(true/false) and deleted_by(S/R) to maintain the message status deleted (true or false) and deleted_by (Sender or Receiver).

An alternative to the other answers (which both could definitely work) would be to have a separate "Inbox" table. Something that just linked up which messages were still in whose inbox, like:
__________________________
| INBOX |
|________________________|
| User | Message_id |
| John | 1 |
| Will | 1 |
|_________|______________|
Then when John deletes the message you delete that row from the inbox table:
__________________________
| INBOX |
|________________________|
| User | Message_id |
| Will | 1 |
|_________|______________|
This way is also nice because it separates the metadata that makes up a message from the info about where it is stored, what actions people have taken, etc.

Add seperate boolean ReadBySender and ReadByReciever columns and update those rather than the actual sender/reciever

Just include two more (enumeration) columns to indicate, who already deleted the message.
Then in order to show the message, make sure in your WHERE clause, that the respective value is not set already.
In any case retain the Sender and Receiver columns, so that you can output all message information and attach the message to the correct users.

Related

How to create users database table for different user access levels

I have an issue about creating database table for user to login in different level access of the system.
I have 3 user roles "ENUM(master_admin, admin_country, admin_city )".
If the master_admin logged in will have access to the whole system,
but if admin_city logged in will have access to his country only with countryID,
and if admin_city logged in will have access to his city data only with cityID
The problem is on creating users table that will save info of different
administrators so they can have access to their related part of the system.
So later when other admin created to cover other parts of the system it will be easily to set them using the same users table.
I tried this:
users table
+--------+-----------+-------------+
| userID | countryID | user_role| |
+--------+-----------+-------------+
| 1 | 23 | master |
+--------+-----------+-------------+
countries table
+-----------+-------------+
| countryID | countryName |
+-----------+-------------+
| 23 | US |
+-----------+-------------+
coutrries table
+-----------+-------------+-------------+
| cityID | countryID | cityName |
+-----------+-------------+-------------+
| 2 | 23 | New York |
+-----------+-------------+-------------+
How can I set my users table for this problem.
Split the users table
users table
+--------+-----------+-----------------+
| userID | username | email |
+--------+-----------+-----------------+
| 1 | adm | master#master |
+--------+-----------+-----------------+
users_Role table
+--------+-----------+------------+-------------+
| userID | countryID | cityID | roleID |
+--------+-----------+------------+-------------+
| 1 | 23 | NULL | 1 |
+--------+-----------+------------+-------------+
| 1 | 22 | NULL | 2 |
+--------+-----------+------------+-------------+
| 1 | NULL | 2 | 3 |
+--------+-----------+------------+-------------+
role table
+-----------+-----------------+
| roleID | roleName |
+-----------+-----------------+
| 1 | Master |
+-----------+-----------------+
| 2 | COUNTRYMASTER |
+-----------+-----------------+
| 3 | CityMaster |
+-----------+-----------------+
OF course you could make a City/Countryid column, as the role defines what type of id is saved.
So can give or remove for every user individual rigst, per country and/or city.
User_role has redundant indormation so another rolentable is necessary for nomalization
You didn't really try all that much, which means your question is reasonable vague. Whenever you design a system with varying levels of access you need to make very sure that access can't be accidentally granted. Even a bug shouldn't make this possible.
A bad way to do this would be to create a cityId in the users table. If there's a number there, say 2, the user has only access to data of New York, if it is 3 only Washington, etc. If the value is zero the user has access to all cities. Choosing zero seems to make sense here, but it is dangerous, because a bug in setting the cityId could set it to zero and give access that shouldn't be granted.
The normal way to do this is to make a separate table which very explicitly grants access. You could call this table permission. Each user can have multiple permissions. You could define a level in it: 'master', 'country' and 'city'. This tells you what kind of access someone has. Other fields could specify exactly which country or city.
Whenever the user accesses a resource you have to check it against the permissions an user has. access is only granted when the answer is positive. You have to write your software in such a way, that forgetting to check the permission, would break the functionality of the software.
I would also log every access, and every change made to the permission table. It might surprise you how often you will have to play detective and find out exactly who did what when.
No matter what you do, this will never be as secure as it can be. There's always a change an user can access something they shouldn't. It could be due to a bug, or a mistake by an administrator. The only way to have real security is to actually put cities and countries in different databases, and let users only exist in the database to which they are allowed to have access. Security and practicality often are enemies.

MySQL choose one field in duplicated values

I have a table of users rights. These rights can be Write or Read. I have a SQL view which merges profile_user table and right_user table. This view give me the following results:
+-------+-----------+---------------+
| email | right | write_or_read |
+-------+-----------+---------------+
| admin | dashboard | write |
+-------+-----------+---------------+
| admin | dashboard | read |
+-------+-----------+---------------+
| admin | log | read |
+-------+-----------+---------------+
How can I un-duplicate dashboard write to get only the most important (the write right).
I want to write an SQL query which gives me the following result:
+-------+-----------+---------------+
| admin | dashboard | write |
+-------+-----------+---------------+
| admin | log | read |
+-------+-----------+---------------+
I read this question but the answer covers only id numeric field to get the right record.
In this case, a simple max() works:
select email, right, max(write_or_read)
from user_rights
group by email, right;
You can use CASE expression to list the conditions in priority. This works for more than two values as well:
SELECT email, right, CASE
WHEN SUM(write_or_read = 'write') > 0 THEN 'write'
WHEN SUM(write_or_read = 'read') > 0 THEN 'read'
-- more conditions
END AS permission
FROM t
GROUP BY email, right

MySQL: How to make sure update is always executed before select?

I am creating a web app that lets N number of users to enter receipt data.
A set of scanned receipts is given to users, but no more than 2 users should work on the same receipt.
i.e. User A and User B can work on receipt-1, but User C can not work on it(Another receipt, say receipt-2, should be assigned to the User C).
The table structure I am using looks similar to the following.
[User-Receipt Table]
+------------+--------------+
| user_id | receipt_id |
+------------+--------------+
| 000000001 | R0000000000 |
| 000000001 | R0000000001 |
| 000000001 | R0000000002 |
| 000000002 | R0000000000 |
| 000000002 | R0000000001 |
+------------+--------------+
[Receipt Table]
+-------------+--------+
| receipt_id | status |
+-------------+--------+
| R0000000000 | 0 |
| R0000000001 | 1 |
| R0000000002 | 0 |
| R0000000003 | 2 |
+-------------+--------+
★status 0:not assigned 1:assigned to a user 2: assigned to 2 users
select receipts from the receipt table whose status is not equal to '2'
insert the receipts fetched from the step 1 along with a user to whom receipts are assigned.
update the receipt status(0->1 or 1->2)
This is how I plan to achieve the above requirement.
The problem with this approach is that there could be a chance that the select(step1) is executed right before the update(step3) is executed.
If this happens, the receipts with status 2 might be fetched and assigned to another user, which does not meet the requirement.
How can I make sure that this does not happen?
For all purposes, use transactions :
START TRANSACTION
your SQL commands
COMMIT
Transactions either let all your statements executed or not executed at all and performs implicitly a lock on the updated row which is more efficient than the second approach
You can also do it using LOCK TABLE

How do I handle linking a record to another table?

I'm very new to Access and my teacher is... hard to follow. So I feel like there's something pretty basic I'm probably missing here. I think the biggest problem I'm having with this question is that I'm struggling to find the words to communicate what I actually need to do, which is really putting a damper on my google-fu.
In terms of what I think I want to do, I want to make a record reference another table in its entirety.
Main
+----+-------+--------+-------+----------------------------+
| PK | Name | Phone# | [...] | Cards |
+----+-------+--------+-------+----------------------------+
| 1 | Bob | [...] | [...] | < Reference to 2nd table > |
| 2 | Harry | [...] | [...] | [...] |
| 3 | Ted | [...] | [...] | [...] |
+----+-------+--------+-------+----------------------------+
Bob's Cards
+----+-------------+-----------+-------+-------+-------+
| PK | Card Name | Condition | Year | Price | [...] |
+----+-------------+-----------+-------+-------+-------+
| 1 | Big Slugger | Mint | 1987 | .20 | [...] |
| 2 | Quick Pete | [...] | [...] | [...] | [...] |
| 3 | Mac Donald | [...] | [...] | [...] | [...] |
+----+-------------+-----------+-------+-------+-------+
This would necessitate an entire new table for each record in the main table though, if it's even possible.
But the only alternative solution I can think of is to add 'Card1, Condition1, [...], Card2, Condition2, [...], Card3, [...]' fields to the main table and having to add another set of fields any time someone increases the maximum number of cards stored.
So I'm sort of left believing there is some other approach I should be taking that our teacher has failed to properly explain. We haven't even touched on forms and reports yet so I don't need to worry about working them in.
Any pointers?
(Also, the entirety of this data and structure is only a rough facsimile of my own, as I'd rather learn how to do it and apply it myself than be like 'here's my data, pls fix.')
Third option successfully found in comments by the helpful Minty.
This depends on a number of things, however to keep it simple you
would normally add one field to the cards table, with an number data
type called CardOwnerID. In your example it would be 1 indicating Bob.
This is known as a foreign key. (FK) - However if you have a table of
cards and multiple possible owners then you need a third table - a
Junction table. This would consist of the Main Person ID and the Card
ID. – Minty

Structuring a MySQL database for user information

I am quite new to MySQL, I know most of the basic functions and how to send queries etc. However, I am trying to learn about structuring it for optimal searches for user information and wanted to get some ideas.
Right now I just have one table (for functionality purposes and testing) called user_info which holds the users information and another table that stores photos linked to the user. Ideally id like most of this information to be as quickly as accessible as possible
In creating a database which is primarily used to store and retrieve user information (name, age, phone, messages, etc.) would it be a good idea to create a NEW TABLE for each new user that stores all the information so the one table user_info does not become bogged down by multiple queries, locking, etc. So for example user john smith would have his very own table in the database holding all his information including photos, messages etc.
OR
is it better to have just a few tables such as user_info, user_photos, user_messages,etc. and accessing data in this manner.
I am not concerned about redundancy in the tables such as the users email address being repeated multiple times.
The latter is the best way. You declare one table for users, and several columns with the data you want.
Now if you want users to have photos, you'd require a new table with photos and a Foreign Key attribute that links to the user table's Primary Key.
You should definitely NOT create a new table for each user. Create one table for user_info, one for photos if each user can have many photos. A messages table would probably contain two user_id columns (user_to, user_from) and a message column. Try to normalize the data as much as possible.
Users
====
id
email
etc
Photos
====
id
user_id
meta_data
etc
Messages
====
id
user_id_to
user_id_from
message
timestamp
etc
I agree with both the answers supplied here, but one thing they haven't mentioned yet is lookup tables.
Going with the general examples here consider this: you have a users table, and a photos table. Now you want to introduce a featre on your site that allows users to "Favorite" photos from other users.
Rather than making a new table called "Favorites" and adding in all your data about the image (fiel location, metadata, score/whatever) all over again, have a table that effectively sits BETWEEN the other two.
+-----------------------+ +-------------------------------------+
| ++ users | | ++ photos |
| userID | email | name | | photoID | ownerID | fileLo | etc... |
+--------+-------+------| +---------+---------+--------+--------+
| 1 | .... | Tom | | 35 | 1 | ..... | .......|
| 2 | .... | Rob | | 36 | 2 | ..... | .......|
| 3 | .... | Dan | | 37 | 1 | ..... | .......|
+--------+-------+------+ | 43 | 3 | ..... | .......|
| 48 | 2 | ..... | .......|
| 49 | 3 | ..... | .......|
| 53 | 2 | ..... | .......|
+---------+---------+--------+--------+
+------------------+
| ++ Favs |
| userID | photoID |
+--------+---------+
| 1 | 37 |
| 1 | 48 |
| 2 | 37 |
+--------+---------+
With this approach, you link the data you have cleanly, efficiently and without too much data replication.