Limit entries to MySQL table, keep unique id fixed - php

I'm posting this here in the hope that someone can give me some ballpark advice as I am a frontend and don't know PHP/MySQL well.
I've heard of triggers but I'm not sure if they are appropriate for my use case. This is more of a conceptual question, before I start the code. Please be kind, I'm a novice :)
I have built a table set up like so:
+-----------+-----------+-------+
| UNIQUE ID | Anchor | URL |
+-----------+-----------+-------+
| 1 | link name | [url] |
| 2 | link name | [url] |
| 3 | link name | [url] |
| 4 | link name | [url] |
+-----------+-----------+-------+
This is linked up to an HTML form where a user can set custom links to appear in a menu.
I would like it to be the case that the MySQL table can only ever have four rows and the unique IDs stay constant and are not overwritten. However the 'Anchor' and 'URL' rows can be overwritten.
This is so that I can have a permanent hook on the row (via a WHERE uniq_id=x SELECT rule) whilst allowing the user generated data to change.
I want it to be the case that the link output to the front end will always be the last one set by the user.
I have really searched but no one seems to've had a similar request which implies I may be going about this completely the wrong way. Grateful if someone could direct me to the right track. Thank you.

Related

I want to be able to search for a Post in the Post table based on whats inside a different table

Inside my post table is my designerID which is the same in the Designer table, when i make a post the designerID is set to the same as it is in the designer table, I want to have a search at the top to allow users to find designers based on what they do, i.e logo design, web design.
The designer table where I have recorded in Boolean what the designer does
Is it possible for me to filter posts based on what ive got?
thanks in advance
I want the user to be able to click a button that says logo which will then only show the posts from designers who ticked logo.
As you said, you are saving the type of work they do in a boolean.
1 representing that they do the type of work
0 representing that they do not do the type of work
If you would like to select all the designers that do logos, this would be your query.
SELECT * FROM designers WHERE logo = 1
This query will give you all the designers that do logos.
You do not need an additional table for categories.
option 1
If you determine that your type will not increase , you can just change
bool to int , when user create a new post, increment the number.
So you can use numbers to determine if he is working on some type,and easy to find
out who is really good at some type.
option 2
create category to recode post types , category_counter to record the numbers of designer working types
category
id | name
--- | ---
1 | logo
2 | website
post_counter
id | designer_id | category_id | number
--- | --- | --- | ---
1 | 1 | 1 | 10
2 | 1 | 2 | 20
3 | 2 | 1 | 5
Maybe my answer is wrong. I apologize for failing to understand the question .

Is it possible to reference a MySQL table dynamically?

I can't find anything about dynamically referencing a MySQL table entry in my particular case. Most everything I've read leans towards it not being possible, but I'm hoping someone can prove me wrong.
Essentially, I've got multiple MySQL tables that I'm trying to pull data from on an Android app. I want to access 2 at a time. The 1st Table's name always stays the same, history. The 2nd Table's name, however, may be different at times. It's value is determined within the app and referenced with :job in my php script (I'll use moon for my example). The 2nd table itself is generated dynamically through the app, so I guess I'm trying to set up a reference within a php script I have saved to a server so that I can access the 2nd Table.
Sorry for the confusing description, I hope these tables will help explain what I'm trying to get at.
Table #1: history (always stays the same)
| site | code | hours|
|---------|---------|------|
| moon | first | 1 |
| moon | second | 2 |
| moon | third | 3 |
| earth | fourth | 4 |
Table #2: moon (this one I want to dynamically reference)
| code | hours|
|---------|------|
| first | 10 |
| second | 11 |
| third | 12 |
And my current code:
...
/*** Table #1 ***/
SELECT code,
SUM(hours) AS total, '' AS target
FROM history
WHERE site = :job /* :job ends up being moon in this example */
GROUP BY code
UNION ALL
/*** Table #2 ***/
SELECT code,
'' AS total, SUM(hours) AS target
FROM :job /* <--- I'm trying to do something along these lines and use 'moon', or 'earth', or whatever... */
GROUP BY code
...
And later I get :job from the app: (moon)
$query_params = array(
':job' => $_POST['jobname'],
);
Result I'm Looking For: (works perfect if I directly use Table #2's name (ie moon) in my php file)
| code | hours|target|
|---------|------|------|
| first | 1 | 10 |
| second | 2 | 11 |
| third | 3 | 12 |
The code absolutely works as expected when I replace the :job in the 2nd table with the actual name of the table. I'm wondering if there is some way to still do it dynamically though?
Thanks for any and all advice!
I've done some pretty extensive searching and haven't come up with anything that works for me.
Is it possible to reference a mysql table entry value from a second table entry dynamically?
https://dev.mysql.com/doc/refman/5.7/en/derived-tables.html
MySQL table.* AS reference
Retrieve parent-child hierarchy from a self-referencing mysql table

Creating a MySQL table upon user registration

I am developing a website which will collect and store information for users.
I need to create a table specific to each individual user on registration to store the information they are searching for using the website. The table created will be named after the newly registered user's username.
Then when the user is logged in and runs the search, the data collected will be stored in a database using a MySQL insert query where the table name is a variable containing the logged-in user's username which will also be the table name.
I am an amateur developer and have searched everywhere to try and find a solution but I cannot seem to find anything evenly remotely similar to my problem.
Thank you in advance for any help!
Creating tables on the fly is more trouble than it's worth and very much swimming against the tide with any SQL database.
The reason you haven't found any docs about the approach you mention is because this problem is generally (almost without exception) solved best by having all the data in one or more tables, and including a column to specify which entity (user) the row is associated with. In your case, this might be an email address, or a username, or just a sequential number.
E.g.
| user_id | email | first_name | last_name | fave_color |
- - - - - -
| 1 | "a#b.c" | "anton" | "aardvark" | "red" |
| 2 | "b#c.d" | "miles" | "o'brien" | "infrared" |
| ... | | | | |
First take name from user like:
$fullname="$fname"."_"."$lname";
Then, write a query like this to create a table of that name
$sql="CREATE TABLE $fullname(ALL THE COLLUMNS YOU WANT TO CREATE)";
$result1=mysql_query($sql, $db_link);
this query is from my project. Works fine in wampserver.

Database Normalisation and Data Entry (admin backend)

Take a look at the items table below, as you can see this table is not normalized. Name should in a separate table to normalize it.
mysql> select * from items;
+---------+--------+-----------+------+
| item_id | cat_id | name | cost |
+---------+--------+-----------+------+
| 1 | 102 | Mushroom | 5.00 |
| 2 | 2 | Mushroom | 5.40 |
| 3 | 173 | Pepperoni | 4.00 |
| 4 | 109 | Chips | 1.00 |
| 5 | 35 | Chips | 1.00 |
+---------+--------+-----------+------+
This table is not normalize because on the backend Admin site, staff simply select a category and type in the item name to add data quickly. It is very quick. There are hundreds of same item name but the cost is not always the same.
If I do normalize this table to something like this:
mysql> select * from items;
+---------+--------+--------------+------+
| item_id | cat_id | item_name_id | cost |
+---------+--------+--------------+------+
| 1 | 102 | 1 | 5.00 |
| 2 | 2 | 1 | 5.40 |
| 3 | 173 | 2 | 4.00 |
| 4 | 109 | 3 | 1.00 |
| 5 | 35 | 3 | 1.00 |
+---------+--------+--------------+------+
mysql> select * from item_name;
+--------------+-----------+
| item_name_id | name |
+--------------+-----------+
| 1 | Mushroom |
| 2 | Pepperoni |
| 3 | Chips |
+--------------+-----------+
Now how can I add item (data) on the admin backend (data entry point of view) because this table has been normalized? I don't want like a dropdown to select item name - there will be thousands of different item name - it will take a lot of of time to find the item name and then type in the cost.
There need to be a way to add item/data quick as possible. What is the solution to this? I have developed backend in PHP.
Also what is the solution for editing the item name? Staff might rename the item name completely for example: Fish Kebab to Chicken Kebab and that will effect all the categories without realising it. There will be some spelling mistake that may need correcting like F1sh Kebab which should be Fish Kebab (This is useful when the tables are normalized and I will see item name updated every categories).
I don't want like a dropdown to select item name - there will be thousands of different item name - it will take a lot of of time to find the item name and then type in the cost.
There are options for selecting existing items other than drop down boxes. You could use autocompletion, and only accept known values. I just want to be clear there are UI friendly ways to achieve your goals.
As for whether to do so or not, that is up to you. If the product names are varied slightly, is that a problem? Can small data integrity issues like this be corrected with batch jobs or similar if they are a problem?
Decide what your data should look like first, based on the design of your system. Worry about the best way to structure a UI after you've made that decision. Like I said, there are usable ways to design UI regardless of your data structuring.
I think you are good to go with your current design, for you name is the product name and not the category name, you probably want to avoid cases where renaming a single product would rename too many of them at once.
Normalization is a good thing but you have to measure it against your specific needs and in this case I really would not add an extra table item_name as you shown above.
just my two cents :)
What are the dependencies supposed to be represented by your table? What are the keys? Based on what you've said I don't see how your second design is any more normalized that your first.
Presumably the determinants of "name" in the first design are the same as the determinants of "item_name_id" in the second? If so then moving name to another table won't make any difference to the normal forms satisified by your items table.
User interface design has nothing to do with database design. You cannot let the UI drive the database design and expect sensible results.
You need to validate the data and check for existence prior to adding it to see if it's a new value.
$value = $_POST['userSubmittedValue']
//make sure you sanitize the variable (never trust user input)
$query = SELECT item_name_id
FROM item_name
WHERE name='$value';
$result = mysql_query($query);
$row = mysql_fetch_row($result);
if(!empty($row))
{
//add the record with the id from $row['item_name_id'] to items table
}
else
{
//this will be a new value so run queries to add the new value to both items and item_name tables
}
There need to be a way to add item/data quick as possible. What is the
solution to this? I have developed backend in PHP.
User interface issues and database structure are separate issues. For a given database structure, there are usually several user-friendly ways to present and change the data. Data integrity comes from the database. The user interface just needs to know where to find unique values. The programmer decides how to use those unique values. You might use a drop-down list, pop up a search form, use autocomplete, compare what the user types to the elements in an array, or query the database to see whether the value already exists.
From your description, it sounds like you had a very quick way to add data in the first place: "staff simply select a category and type in the item name to add data quickly". (Replacing "mushroom" with '1' doesn't have anything to do with normalization.)
Also what is the solution for editing the item name? Staff might
rename the item name completely for example: Fish Kebab to Chicken
Kebab and that will effect all the categories without realising it.
You've allowed the wrong person to edit item names. Seriously.
This kind of issue arises in every database application. Allow only someone trained and trustworthy to make these kinds of changes. (See your dbms docs for GRANT and REVOKE. Also take a look at ON UPDATE RESTRICT.)
In our production database at work, I can insert new states (for the United States), and I can change existing state names to whatever I want. But if I changed "Alabama" to "Kyrgyzstan", I'd get fired. Because I'm supposed to know better than to do stuff like that.
But even though I'm the administrator, I can't edit a San Francisco address and change its ZIP code to '71601'. The database "knows" that '71601' isn't a valid ZIP code for San Francisco. Maybe you can add a table or two to your database, too. I can't tell from your description whether something like that would help you.
On systems where I'm not the administrator, I'd expect to have no permissions to insert rows into the table of states. In other tables, I might have permission to insert rows, but not to update or delete them.
There will be some spelling mistake that may need correcting like F1sh
Kebab which should be Fish Kebab
The lesson is the same. Some people should be allowed to update items.name, and some people should not. Revoke permissions, restrict cascading updates, increase data integrity using more tables, or increase training.

pending data approval

I have a website that allows users with accounts. Account profiles are displayed on the front end of a website. Users can login and update their data, but it all must be approved by an admin (on a form) before the front end content reflects their update. The "live" data is stored across multiple tables in a Postgresql DB.
I'm looking for ideas for the (best / easiest) way to handle storing (db schema) this updated data that will allow an admin user to
approve/deny updates independently for a user (approve update A, deny update B, and ignore update C)
Be easy to maintain
Be easy for me to pull the updates to show admin and then process each individual field request.
Admin will need to be able to see a list of all users that have pending updates and then be able to see which fields for a specific user was updated so they can approve/deny the request.
Users can freely update a field as many times as they want, but admin will always see the current field content and the last update the user made.
I don't need to be able to see exact differences (although brownie points if you know how). They really just need to be able to see the two fields
ie:
Current Update
+--------------+-------------+-------------+
| | | (o) Approve |
| description | Description | |
| | | (o) Deny |
+--------------+-------------+-------------+
| | | (o) Approve |
| title | Title | |
| | | (o) Deny |
+--------------+-------------+-------------+
| [Submit] |
+------------------------------------------+
I'm open to any and all ideas, DB techniques, programming, or something else I haven't thought of.
Thanks in advance!
It's just a status of a record, an extra column in your tables holding the current status will be enough.

Categories