Since RedBean creates all columns by itself what would happen if I don't need a field any more. Is there an easy way to remove it without deleting the table and lose all data?
Can this be solved automaticaly or how would RedBean react if I delete the column manually?
Delete the table column in the usual way from your MySQL client (say, phpMyAdmin or SQLYog) or from the MySQL console.
RedBean can't get confused by this "external meddling" that you're worried about, because it runs on each PHP script execution and, to the best of my knowledge, carries no state across invocations. It's really just an abstraction over data storage.
Interestingly, the RedBean Wiki doesn't appear to talk about this sort of thing at all.
Related
I am using mysql database for my site.
I have create one site using codeigniter php framework and mysql.
Now after few months I have updated that site and also the database.
I have added some new columns to my database table not deleted or alert any previous one.
Now I want to update my site but don't want to lose data that I already have right now.
Is there anyway I can update database without losing the data present in it.
If your database is created/updated automatically by some modeling tool, I think the best you way you should do is to understand those changes and write the "alter table" statements yourself and run it in your deployment.
As user1281385 pointed in answer https://stackoverflow.com/a/22012478/1033539 , there may be some tool that can help you generate those statements.
SQLyog has a great feature called "Schema Synchronization tool" which will do it
they also have a blog comparing other methods of doing it
http://blog.webyog.com/2012/10/16/so-how-do-you-sync-your-database-schema/
Im sure other similar tools can do it also
Edit:
Mysql Workbench also has this feature
http://www.mysql.com/products/workbench/features.html
I have just been tasked with recovering/rebuilding an extremely large and complex website that had no backups and was fully lost. I have a complete (hopefully) copy of all the PHP files however I have absolutely no clue what the database structure looked like (other than it is certainly at least 50 or so tables...so fairly complex). All data has been lost and the original developer was fired about a year ago in a fiery feud (so I am told). I have been a PHP developer for quite a while and am plenty comfortable trying to sort through everything and get the application/site back up and running...but the lack of a database will be a huge struggle. So...is there any way to simulate a MySQL connection to some software that will capture all incoming queries and attempt to use the requested field and table names to rebuild the structure?
It seems to me that if i start clicking through the application and it passes a query for
SELECT name, email, phone from contact_table WHERE
contact_id='1'
...there should be a way to capture that info and assume there was a table called "contact_table" that had at least 4 fields with those names... If I can do that repetitively, each time adding some sample data to the discovered fields and then moving on to another page, then eventually I should have a rough copy of most of the database structure (at least all public-facing parts). This would be MUCH easier than manually reading all the code and pulling out every reference, reading all the joins and subqueries, and sorting through it all manually.
Anyone ever tried this before? Any other ideas for reverse-engineering the database structure from PHP code?
mysql> SET GLOBAL general_log=1;
With this configuration enabled, the MySQL server writes every query to a log file (datadir/hostname.log by default), even those queries that have errors because the tables and columns don't exist yet.
http://dev.mysql.com/doc/refman/5.6/en/query-log.html says:
The general query log can be very useful when you suspect an error in a client and want to know exactly what the client sent to mysqld.
As you click around in the application, it should generate SQL queries, and you can have a terminal window open running tail -f on the general query log. As you see queries run by that reference tables or columns that don't exist yet, create those tables and columns. Then repeat clicking around in the app.
A number of things may make this task even harder:
If the queries use SELECT *, you can't infer the names of columns or even how many columns there are. You'll have to inspect the application code to see what column names are used after the query result is returned.
If INSERT statements omit the list of column names, you can't know what columns there are or how many. On the other hand, if INSERT statements do specify a list of column names, you can't know if there are more columns that were intended to take on their default values.
Data types of columns won't be apparent from their names, nor string lengths, nor character sets, nor default values.
Constraints, indexes, primary keys, foreign keys won't be apparent from the queries.
Some tables may exist (for example, lookup tables), even though they are never mentioned by name by the queries you find in the app.
Speaking of lookup tables, many databases have sets of initial values stored in tables, such as all possible user types and so on. Without the knowledge of the data for such lookup tables, it'll be hard or impossible to get the app working.
There may have been triggers and stored procedures. Procedures may be referenced by CALL statements in the app, but you can't guess what the code inside triggers or stored procedures was intended to be.
This project is bound to be very laborious, time-consuming, and involve a lot of guesswork. The fact that the employer had a big feud with the developer might be a warning flag. Be careful to set the expectations so the employer understands it will take a lot of work to do this.
PS: I'm assuming you are using a recent version of MySQL, such as 5.1 or later. If you use MySQL 5.0 or earlier, you should just add log=1 to your /etc/my.cnf and restart mysqld.
Crazy task. Is the code such that the DB queries are at all abstracted? Could you replace the query functions with something which would log the tables, columns and keys, and/or actually create the tables or alter them as needed, before firing off the real query?
Alternatively, it might be easier to do some text processing, regex matching, grep/sort/uniq on the queries in all of the PHP files. The goal would be to get it down to a manageable list of all tables and columns in those tables.
I once had a similar task, fortunately I was able to find an old backup.
If you could find a way to extract the queries, like say, regex match all of the occurrences of mysql_query or whatever extension was used to query the database, you could then use something like php-sql-parser to parse the queries and hopefully from that you would be able to get a list of most tables and columns. However, that is only half the battle. The other half is determining the data types for every single column and that would be rather impossible to do autmatically from PHP. It would basically require you inspect it line by line. There are best practices, but who's to say that the old dev followed them? Determining whether a column called "date" should be stored in DATE, DATETIME, INT, or VARCHAR(50) with some sort of manual ugly string thing can only be determined by looking at the actual code.
Good luck!
You could build some triggers with the BEFORE action time, but unfortunately this will only work for INSERT, UPDATE, or DELETE commands.
http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html
The server is a shared Windows hosting server with Hostgator. We are allowed "unlimited" MS SQL databases and each is allowed "unlimited" space. I'm writing the website in PHP. The data (not the DB schema, but the data) needs to be versioned such that (ideally) my client can select the DB version he wants from a select box when he logs in to the website, and then (roughly once a month) tag the current data, also through a simple form on the website. I've thought of several theoretical ways to do this and I'm not excited about any of them.
1) Put a VersionNumber column on every table; have a master Version table that lists all versions for the select box at login. When tagged, every row without a version number in every table in the db would be duplicated, and the original would be given a version number.
This seems like the easiest idea for both me and my client, but I'm concerned the db would be awfully slow in just a few months, since every table will grow by (at least) its original size every month. There's not a whole lot of data, and there probably never will be, in any one version. But multiplying versions in the same table just scares me.
2) Duplicate the DB every time we tag.
It looks like this would have to be done manually by my client since the server is shared, so I already dislike the idea. But in addition, the old DBs would have to be able to work with the current website code, and as changes are made to the DB structure over time (which is inevitable) the old DBs will no longer work with the new website code.
3) Create duplicate tables (with the version in their name) inside the same database every time we tag. Like [v27_Employee].
The benefit here over idea (1) would be that no table would get humongous in size, allowing the queries to keep up their speed, and over idea (2) it could theoretically be done easily through the simple website tag form rather than manually by my client. The problems are that the queries in my PHP code are going to get all discombobulated as I try to explain which Employee table is joining with which Address table depending upon which version is selected, since they all have the same name, but different; and also that as the code changes, the old DB tables no longer match, same problem as (2).
So, finally, does anyone have any good recommendations? Best practices? Things they did that worked in the past?
Thanks guys.
Option 1 is the most obvious solution because it has the lowest maintenance overhead and it's the easiest to work with: you can view any version at any time simply by adding #VersionNumber to your queries. If you want or need to, this means you could also implement option 3 at the same time by creating views for each version number instead of real tables. If your application only queries one version at a time, consider making the VersionNumber the first column of a clustered primary key, so that all the data for one version is physically stored together.
And it isn't clear how much data you have anyway. You say it's "not a whole lot", but that means nothing. If you really have a lot of data (say, into hundreds of millions of rows) and if you have Enterprise Edition (you didn't say what edition you're using), you can use table partitioning to 'split' very large tables for better performance.
My conclusion would be to do the simplest, easiest thing to maintain right now. If it works fine then you're done. If it doesn't, you will at least be able to rework your design from a simple, stable starting point. If you do something more complicated now, you will have much more work to do if you ever need to redesign it.
You could copy your versionable tables into a new database every month. If you need to do a join between a versionable table and a non-versionable table, you'd need to do a cross-schema join - which is supported in SQL Server. This approach is a bit cleaner than duplicating tables in a single schema, since your database explorer will start getting unwieldy with all the old tables.
What I finally wound up doing was creating a new schema for each version and duplicating the tables and triggers and keys each time the DB is versioned. So, for example, I had this table:
[dbo].[TableWithData]
And I duplicated it into this table in the same DB:
[v1].[TableWithData]
Then, when the user wants to view old tables, they select which version and my code automatically changes every instance of [dbo] in every query to [v1]. It's conceptually fairly simple and the user doesn't have to do anything complicated to version -- just type in "v1" to a form and hit a submit button. My PHP and SQL does the rest.
I did find that some tables had to remain separate -- I made a different schema called [ctrl] into which I put tables that will not be versioned, like the username / password table for example. That way I just duplicate the [dbo] tables.
Its been operational for a year or so and seems to work well at the moment. They've only versioned maybe 4 times so far. The only problem I seem to have consistently that I can't figure out is that triggers seem to get lost somehow. That's probably a problem with my very complex PHP rather than the DB versioning concept itself though.
I am working on a web based application using Zend framework.
I am looking for a way to keep history of updates made to a bunch of columns.
Use-case:
User can add an item with 5 properties. The user is allowed to update the 5 properties. I need to track all the updates he makes to those 5 properties.
On way I thought of was adding a new table named log which stores the old value, new value, column name, itemID and timestamp.
What is the best way to do this? Are there any existing methods/options/examples ?
Thanks,
What you're probably looking for is an audit log. You can create one using Triggers on your MySQL database.
An example of how to do this is here: http://ronaldbradford.com/blog/auditing-your-mysql-data-2008-07-15/
In your comment below you added that the database is not 'fixed'. In that case, you'd have to replicate any alters to the table so that they are applied to the audit table in such a way that any newly added columns are added to the log as well.
You can consider logging this in your application (as your tags chosen for this question seem to suggestion) - but keep in mind that this means there can be situations where your log does not provide the complete answer. Triggers, stored procedures and any manual interventions in the database will not be logged... so be careful if you choose to go down that path.
Triggers are the most common way to do auditing and the only really reliable way to capture what was done whether done from the user interface or elsewhere. They do vary by database in how they would be written though. If you know the possible types of database backends you will support, you could write separate triggers for each.
If you must handle this without triggers, then your best bet is to have a process that writes to the audit table as well as makes the update change. It might be complex enough to warrant a stored proc called by the Zend framework rather than relying on the framework itself to do. (I'm not familair with Zend so I don't know if this is something that could be set up, I know a stored proc could handle this.)
Here is a better one..
See Pop On the Audit Trail
I just created a new table called it Comp_Hist_Log and then defined the old data in the
BEFORE UPDATE hook
$oldData = $array('fieldname1', 'fieldname2')
Then at the AFTER_UPDATE hook in my database gui hook file.. I added this code
sql("INSERT INTO Comp_Hist_Log (Com_Rec_Id, old_data, new_data, ChangedDate, ChangedBy)
VALUES('{$data['Record_Id']}', '{$oldData}', '{$messageData}', '{$data['LastUpdated']}', '{$memberInfo['username']}')", $eo);
return TRUE;
Hope it helps.. it does work.
Brief background - Im writing a special import manager to be run via cron. The basic operation is:
Delete all records from table
Load data from a file or a string into the table
Not to difficult, however because of the apocolyptic delete at the beginning of this sequence id like to use a transaction so i can rollback if anything goes wrong during the process. However, some of the tables updated by this process are MyIsam which doesnt support transactions.
So the main question is: Is there an easier way to detect the storage engine for a given table than doing a show create table and then doing what little parsing it takes to get the storage engine - ie. id like to avoid this extra query.
Secondly: I havent actually tried this yet as im still writing soem other pieces that fit in - so perhaps Zend_Db simply ignores beginTransaction,commit, and rollback if not supported on the table in question?
Also Im not using Zend_Db_Table for this - just the Adapter (Pdo_Mysql). Alternatively im perfectly willing to use raw PDO if that somehow allows a more elegant solution.
(Im not interested in using mysqlimport for this particular implementation for a number of reasons im not going to get into so lets just say its not an option at all)
I'd suggest solving your problem with renaming the original table and deleting it after successful completion ;)
Don't know if this is still relevant for you, but what about this response:
How can I check MySQL engine type for a specific table?