I'm working with SQLite in php, and I was just attempting to add a new column to table, and I went into my table.db file to check if it added it, and I noticed that I have 2 Users tables.
This is really weird to me, because I'm not sure how I have 2 tables with the same name? It also appears to save all of the data twice (Once to either table), which I believe is why I have been having some stability issues.
in my db file I have ā€˛CtableUsersUsersCREATE TABLE Users( and ā€˛%tableUsersUsersCREATE TABLE Users(
So my question is: Is this normal behavior? I'm fairly new to SQLite. And if not, how can I safely remove the 2nd table without deleting the 1st table at the same time?
Some old data might still be in unused parts of some pages. This is harmless.
If it bothers you, run VACUUM.
Related
Background: A group of students including me are creating a website for a merit system for our school. We basically had no experience in html, css, php or sql databases at the start. I will say we've managed decently.
However, we've run into a problem with updating the database. Every week, we need to merge the table for students from a csv, which is updated with classes and all from a department of education system. So there are thousands of students and each of them have certain details that when updated can change but others that need to stay the same. For example, we have the number of merits which needs to stay the same when we update but details such as their year group or classes can change. The thing is, is that this update is done of a csv file which may also have new students that need to be updated to the database and the csv is not in any order. So we are trying to find a solution which allows one field to be the same but allow others to change.
So we've tried LOAD DATA INFILE with a unique key but the problem we found was that while it preserved the merits, it ignored the other details and just added new students.
EDIT: So the students have a class field which contains the classes of the student. When we import, we need to be able to change that but still maintain the merit field which will not be in the csv file. We understand that we could just manually import it but suspect that will take a long time to run.
Our code will be in PHP by the way.
tl;dr
Need to find out how to merge/import databases from csv, changing only specific fields of existing students and also adding new students
Thanks in advance for your help and sorry for the long post. This is my first post so do forgive me if I make any mistakes.
You will need a php script which reads the contents of the file, line by line preferably since it is a CSV. You will then need to use the primary key unique identifier from each CSV line to check whether a record with that primary key value already exists in the database. If a record with that primary key exists in the database, use the UPDATE query to update the merits only. If a record cannot be found with that primary key, use the INSERT statement to add that new record to the database.
NOTE: Bolded bits are steps required, in chronological order.
I have a few nagging questions about creating tables:
If I use PHP to create a MySQL function to create a table, I know it works the first time (to create a database for usernames and passwords) but what about the following times when the database sees the code to "create table". It seems to ignore it on my virtual server, but I was just wondering if this is wrong. Does it keep trying to create a new table each time? Is it okay to leave that code in?
Another question I have is, let's say I go into PHPMyAdmin and add a column called "role" (to define the user's role). The sign in page will crash since I added a column in PHPMyAdmin, but if add the column using PHP/MySQL it is perfectly fine. Why is that?
CREATE TABLE is executed each time you run the function. It's better to replace the syntax with CREATE TABLE IF NOT EXISTS.
The keywords IF NOT EXISTS prevent an error from occurring if the
table exists.
If you does not add IF NOT EXISTS it will throw the error.
Reference: http://dev.mysql.com/doc/refman/5.7/en/create-table.html
Please post your code in question to help you with second query.
1.) It depends on the purpose of the table.
If you need to create tables dynamically then your code should check each time
if the table exists:
CREATE TABLE IF NOT EXISTS 'yourTable'
However if you create the table only ones, there is no need to check for existence over and over again, so the code to create these table(s) should execute one time only.
2.) You need to update the function that does the insert or read after adding a column via PHPMyAdmin. It's difficult to answer your second question as I don't know what your functions do.
Do not keep your CREATE TABLE ... statements in your PHP code so that they execute every single time on every single page load. It's unnecessary and error prone. The statements are not being ignored, very likely they are run and are producing errors, and you're simply not checking for errors.
Database creation is a deployment step, meaning when you upload your code to your server, that's the one and only time when you create or modify databases. There are entire toolchains available around managing this process; learn something about automated deployment processes and database schema versioning at some point.
No idea without seeing your code and the exact error message.
I'm working on a database with many related tables and I recently learned (yesterday) that in order for my related columns to update automatically when I make changes to the PARENT key, I need to set the relation up with "On Update" constraints. However, the more I research on how to do this through my PHPMyAdmin interface, the more I realize that I'm missing something in my version of PHPMyAdmin.
Apparently I should be able to do this through "Relation View" under my "Structure" tab. Problem is, I don't have that option (See img)
What you see is all that's available on that page.
After digging around a little bit more, I realized that if I go through my "Designer" Page (see img):
Then I'm able to access something that actually talks about "On Update" (see img)
The only problem now is that I can't seem to "Create" my Relations with "On Update" because these foreign relations already exist. (Head-Desks)
Questions:
1.)Why do I not have the "ON UPDATE" option under my "Relation View" Where it is apparently supposed to be? I'm using MAMP 3.2.1 and PHPMyAdmin 4.4.1.1 (latest version) and my Storage Engine is InnoDB.
2.)Given that, is there any way outside of using SQL that I can add the "ON UPDATE" constraints through my PHPMyAdmin interface to my already existing foreign keys?
3.)If not, what would be the SQL that I'd need in order to do this "By Hand". Generic examples would be fine.
UPDATE:
So I decided to try and remove some of my relations in order to re-connect them with the DESIGNER interface which appeared to have what I wanted. However, when I did so and attempted to create the connection, I got this:
What happened to my "ON UPDATE" options?!
I had lot of issues like this with phpmyadmin. So i recommend you to Download Mysql workbench and use it instead of phpmyadmin. Work bench is way better than php my admin. Download it here
https://www.mysql.com/products/workbench/
Ok, I was able to figure out my problem. Well, not my problem, I still don't know why I don't have CONSTRAINT fields in my RELATION VIEW in PHPMyAdmin. But I was able to figure out a way around it. Jiji John suggested that I download MySQL Workbench, which I did but couldn't figure out how to work at first. Then I realized the reason it wasn't working was because I was making tons of mistakes. Which makes sense, I'm still pretty new at this. But I'm still not very comfortable with the MySQL Workbench interface. I don't feel it's as intuitive as PHPMyAdmin.
So this is what I did to convert ALL my (many) tables to ON UPDATE CASCADE. I'm sure there was a more efficient way to do this, but at least this got it done:
Since all SQL attempts seemed to be having issues with all my current tables, I individually copied each table one-by-one to a new database through PHPMyAdmin's Operations Tab.
First, I copied the Referenced Tables that didn't have any foreign keys, to which I added the prefix NFK (No Foreign Keys) so I'd have a visual reference of which tables I didn't need to mess with.
After I'd copied over all my NFK tables, I worked on the remaining tables in the order that required the fewest to largest amounts of foreign keys.
First I'd copy just the table structure (no data) from the first database to the 2nd one.
Then I'd head over to MySQL Workbench to add the necessary foreign keys and ON UPDATE constraints since PHPMyAdmin won't do that for me.
After that I would copy the export SQL from the original table and paste it into the SQL field of the 2nd database.
Finally I would add the prefix OUC (On Update Cascade) to the new table so I'd know I was done with it, and then I'd hide the table on the old database so I'd know I was done with THAT.
I know this is a bit graphic heavy, but I'm a very visual person, especially when it comes to things I don't understand. So I hope all these graphics will help someone who was having trouble like I was. I do appologies for how large the images are. I was simply taking screen shots from my computer, I'm not sure how I'd make them smaller . . .
You probably are using MyIsam as storage engine.
That doesn't support foreign key constraints. Looking at a MyIsam table in any of my databases gives me the same as your screenshot.
Same server, same database, but innodb engine gives:
Basically, I am trying to create an interface that will tell an administrator "Hey, we ran this query, and we weren't so sure about it, so if it broke things click here to undo it".
The easiest way I can think to do this is to somehow figure out what tables and cells an identified "risky" query writes to, and store this data along with some bookkeeping data in a "backups" table, so that if necessary the fields can be repopulated with their original contents.
How do I go about figuring out which fields get overwritten by a particular (possibly complicated) mysql command?
Edit: "risky" in terms of completing successfully but doing unwanted things, not in terms of throwing an error or failing and leaving the system in an inconsistent state.
I suggest the following things:
- add an AFTER UPDATE trigger to every table you want to monitor
- create a copy of every table (example: [yourtable]_backup) you want to monitor
- in all AFTER UPDATE triggers, add code: INSERT INTO yourtable_backup VALUES(OLD.field1, OLD.field2..., OLD.fieldN)
How it works: the AFTER UPDATE trigger detects an update of the table, and backups the old values into the backup table
Important: you need to use INNODB table format for triggers to work. Triggers don't work with MyISAM tables.
You may add a timestamp field to the backup tables to know when each row was inserted.
Documentation: http://dev.mysql.com/doc/refman/5.5/en/create-trigger.html
I have a mysql database. What I'd like to do is perform an arbitrary action on it, and then figure out what changed. Something like this:
//assume connection to db already established
before();//saves db state
perform_action();//does stuff to db
diff();//prints what happened
I'd want it to output something like:
Row added in table_0 ]details]
Row added in table_1 [details]
Row modified in table_5 [details]
Row deleted in table_2 [details]
Any ideas?
To further clarify: You know how on stackoverflow, if you check a post's edits, you can see red lines/green highlights indicating what's been changed? I want something like that, but for mysql databases.
Instead of copying your whole database in order to save the state for a later diff, you might be better off by using triggers:
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
When you setup appropriate triggers, you can log changes to a table - for example, you can setup a trigger that automatically logs the old values and the new values for every update. To see the changes, query the table that was filled by the trigger.
Of course, the trigger is not restricted to changes made by your application, it will also log updates done by other applications. But this is also the case if you diff the old version of the database with the new version of the database.
I think normally your application would log any interesting changes as it makes them. Or you would set up history tables for everything with datetimes.
To do it the way you describe, you could dump the contents of the database into a file before and after your action and do a diff on the two files. In php, you can check out xdiff: http://us.php.net/manual/en/book.xdiff.php
If this is something you're doing only occasionally in controlled circumstances to test some queries you're not sure about, you can dump and diff on the command line.
One way is to parse the log files, which will give you exact SQL statements executed in your database. I'm not exactly sure how to separate SQL statements made by your application from other applications (if thats the case)
The only thing I can think of is to do some combination of a few somewhat hackey things:
Save a [temporary?] table of row IDs, to check for new rows. If you need to know what was in deleted or modified rows before, you'll need to copy the whole DB, which would be rather messy.
Have each row have a datestamp that gets modified on update; grab rows for whom the updated datestamp is newer than when the analysis started.
Have a layer between your application and the database (if you have something like the classic $db->query(), it would make this easy), log queries sent, which can then be looked at.
I suppose the real question is if you want to know what queries are being executed against the DB, or if you want to know what they queries you're running are actually doing.