How to check last modify of a field in MySQL - mysql

I have a MySQL database preinstalled. I don't wont modify it. Does exist a built in method to check which and when a field has been modified in a specific table?

No, there's no built in method that does this in MySQL.
If you want this type of operation performed in the database, you would need to roll your own solution; and that would require you to modify the database, by adding tables and triggers to audit changes, for example.

Related

MySQL Update of Columns using INFORMATION_SCHEMA - is this possible?

I know that I can view the properties and do some amazing things to learn my db/table/field structure using INFORMATION_SCHEMA.
However, is it possible to update a field value in for example the COLUMNS table and thus update the actual column? For example setting nullable from NO to YES.
If this is not directly possible, I realize that I could use the query to CONCAT an ALTER string and then run those strings. However is there in that case a way to instead run an eval() command to do this in one operation? Thanks.
To learn INFORMATION_SCHEMA: I'd start from reading documentation - INFORMATION_SCHEMA Tables. Then I'd try to edit objects and see what happens in these tables.
INFORMATION_SCHEMA tables are system tables, they cannot be modified. ALTER TABLE is the only way to change a table.
It was a beautiful idea, but unfortunately, it won't work.
The tables in INFORMATION_SCHEMA are read-only views, and are not actually tables. So there aren't any files or directories associated with them. You can only read their contents and can't run INSERT, UPDATE, or DELETE operations on them.
See https://dev.mysql.com/doc/refman/5.7/en/information-schema-introduction.html#information-schema-usage-notes for the lowdown.
And FYI, there's a Database Administrators Stack Exchange site if you want more targeted answers to database questions.

how do I determine the time an entry was made into a mysql table without adding a new column

As the title says...
How do I determine the time an entry was made into a mysql table without adding a new column? I realize that I could add a table.created TIMESTAMP column but I'd rather not do this. I'm using MySQL 5.1
I don't think you can do that. If you could, then timestamp columns would be unnecessary.
Why the reluctance to use a column?
Well, you first need to figure out where you want this data to be stored. mySql doesn't just automatically track when rows are created or updated, so that means it's up to you to store it.
Your first option is to store it in the database. This means altering your table and adding a new column, or storing it elsewhere in the database. If you want to store the information in another table, you have to modify the code that does the insert to also log the data - or use a TRIGGER to automatically log the data.
If you don't want to store the data in the database, you could perhaps use a logging library to write the information to an event log or file. You'd have to modify the code that does the insert to also log this data through that mechanism.
Hope this helps.

Entity Framework 4.1 Custom Database Initializer strategy

I would like to implement a custom database initialization strategy so that I can:
generate the database if not exists
if model change create only new tables
if model change create only new fields without dropping the table and losing the data.
Thanks in advance
You need to implement IDatabaseInitializer interface.
Eg
public class MyInitializer : IDatabaseInitializer<MyDbContext>
{
public void InitializeDatabase(MyDbContext context)
{
//your logic here
}
}
And then set your initializer at your application startup
Database.SetInitializer<ProductCatalog>(new MyInitializer());
Here's an example
You will have to manually execute commands to alter the database.
context.ObjectContext.ExecuteStoreCommand("ALTER TABLE dbo.MyTable ADD NewColumn VARCHAR(20) NULL");
You can use a tool like SQL Compare to script changes.
There is a reason why this doesn't exist yet. It is very complex and moreover IDatabaseInitializer interface is not very prepared for such that (there is no way to make such initialization database agnostic). Your question is "too broad" to be answered to your satisfaction. With your reaction to #Eranga's correct answer you simply expect that somebody will tell you step by step how to do that but we will not - that would mean we will write the initializer for you.
What you need to do what you want?
You must have very good knowledge of SQL Server. You must know how does SQL server store information about database, tables, columns and relations = you must understand sys views and you must know how to query them to get data about current database structure.
You must have very good knowledge of EF. You must know how does EF store mapping information. You must be able to explore metadata get information about expected tables, columns and relations.
Once you have old database description and new database description you must be able to write a code which will correctly explore changes and create SQL DDL commands for changing your database. Even this look like the simplest part of the whole process this is actually the hardest one because there are many other internal rules in SQL server which cannot be violated by your commands. Sometimes you really need to drop table to make your changes and if you don't want to lose data you must first push them to temporary table and after recreating table you must push them back. Sometimes you are doing changes in constraints which can require temporarily turning constrains off, etc. There is good reason why tools which do this on SQL level (comparing two databases) are probably all commercial.
Even ADO.NET team doesn't implemented this and they will not implement it in the future. Instead they are working on something called migrations.
Edit:
That is true that ObjectContext can return you script for database creation - that is exactly what default initializers are using. But how it could help you? Are you going to parse that script to see what changed? Are you going to execute that script in another connection to use the same code as for current database to see its structure?
Yes you can create a new database, move data from the old database to a new one, delete the old one and rename a new one but that is the most stupid solution you can ever imagine and no database administrator will ever allow that. Even this solution still requires analysis of changes to create correct data transfer scripts.
Automatic upgrade is a wrong way. You should always prepare upgrade script manually with help of some tools, test it and after that execute it manually or as part of some installation script / package. You must also backup your database before you are going to do any changes.
The best way to achieve this is probably with migrations:
http://nuget.org/List/Packages/EntityFramework.SqlMigrations
Good blog posts here and here.

Is there any way to automatically create a trigger on creation of new table in MySQL?

Is there any way to automatically create a trigger on creation of new table in MySQL?
As I've pointed out in your other question, I think a process and security review is in order here. It's an audited database, so nobody (especially third-party service providers) should be creating tables in your database without your knowledge.
The issue you've got is, as well as the new table being created, you will also need to have another table created to store the audited/changed records, which will have an identical structure as the original table with possibly a time/date and user column. If a third-party provider is creating this table, they won't know to create the auditing table, therefore even if you could generate your triggers dynamically, they wouldn't work.
It's impossible to create a single table that will hold all changes record for all other tables in your database because the structure between tables inevitably differs.
Therefore: make all change requests (e.g. providers wants to create TableX, they submit a change request (including the SQL script) explaining the reason for the change) to yourself and/or your team.
You execute the SQL on a test copy of your database, and use the same structure to create another table to hold the modified records.
You then create and test the necessary triggers, generate a new SQL script to create the two tables and your triggers and execute that on your live database. You give your provider permissions to use the new table and away they go.
Everyone's happy. Yes, it may take a little while longer, and yes you'll have more work to do, but that's a hell of a lot less work than is required to try and parse query logs to re-create records that have already been changed/deleted, or parse the binary log and keep up-to-date with every change, and modify your code when the format of the log file changes etc etc.

How to version control data stored in mysql

I'm trying to use a simple mysql database but tweak it so that every field is backed up up to an indefinite number of versions. The best way I can illustrate this is by replacing each and every field of every table with a stack of all the values this field has ever had (each of these values should be timestamped). I guess it's kind of like having customized version control for all my data..
Any ideas on how to do this?
The usual method for "tracking any changes" to a table is to add insert/update/delete trigger procedures on the table and have those records saved in a history table.
For example, if your main data table is "ItemInfo" then you would also have an ItemInfo_History table that got a copy of the new record every time anything changed (via the triggers).
This keeps the performance of your primary table consistent, yet gives you access to the history of any changes if you need it.
Here are some examples, they are for SQL Server but they demonstrate the logic:
My Repository table
My Repository History table
My Repository Insert trigger procedure
My Repository Update trigger procedure
Hmm, what you're talking about sounds similar to Slowly Changing Dimension.
Be aware that version control on arbitrary database structures is officially a rather Hard Problem. :-)
A simple solution would be to add a version/revision field to the tables, and whenever a record is updated, instead of updating it in place, insert a copy with the changes applied and the version number incremented. Then when selecting, always choose the record with the latest version. That's roughly how most such schemes are implemented (e.g. Wikimedia does it pretty much this exact way).
Maybe a tool can help you to do that for you. Have a look at nextep designer :
https://github.com/christophefondacci/nextep-designer
With this IDE you will be able to take snapshots of your database structure and data and put it under version control. After this you can compute the differences between any 2 versions and generate the appropriate SQL that can insert / update / delete your data.
Maybe this is an alternative way to achieve what you wanted.