I try to insert data into a mySQL table and i don't know yet how many parameters there will be.
So i need to find out a way how to insert parameters dynamically.
You can do it that way:
Insert into mytable (parameters) VALUES ('Ford;red;100kW;diesel;');
Insert into mytable (parameters) VALUES ('Ford;red;100kW;electric;40kWH');
So if you have to add a electric car, you need the kWH, which you didn't need for the petrol car.
Or you do it that way:
Insert into mytable(name, color, kW, engine) VALUES ('Ford', 'red', '100', 'diesel')
ALTER TABLE mytable ADD kWh VARCHAR( 255 ) after engine
Insert into mytable(name, color, kW, engine, kWh) VALUES ('Ford', 'red', '100', 'electric', '40')
In first case you have to hande all the data with string operations like explode, in second case you have to allow the user to add columns with php.
What is the better way? Or is there another way that is even better?
I don't see any similarity with the other question.
This is a verry dificult question. I hope i understood it correctly.
Disclaimer
This is a long post, it may contain errors. Feel free to correct those or ask for clarifiation. It also is (because of the nature of the question) somewhat oppinion based. I tried to balance all possibilities.
I assumed a object orriented approach to this, i.e. that object should be stored.
TL;DR: It might be best to not do this programmatically.
Evaluation
The first answer has the advantage, that you may split the text at runtime and dynamically create a new Object, which will not lead to a PDOException (or whatever you are using). This however also has it's disadvantages. It can lead to you using reflections a lot. Why? If you want to alter the Table at runtime, i have to asume you do not know what kind of Objects are to be expected. This leads to you creating those objects "on the fly". This would also suggest, that you should store the Objects name somehow.
The seconds answer raises a Question. How do you read from that Database?
If you dynamically read of that database (i.e. programmatically defining which columns you are going to need): How do you know, which columns to read from? What ensures you, that the columns will exist? You would have to check that the column you request exists. This may get messy real fast, because you would have to check for each column. And if it does exist, but is not set, what will be the default value for it?
If you statically read of that database: Why not design the database beforehand to hold the kWh column? It might be null at some point, but you could compensate for that, by ignoring them.
If you know the Object you want to use beforehand, design your Database to be able to hold it.
Another way to aproach this
Or is there another way that is even better?
You may be happy to use Relational Databases and abstruct those with a Data Access Object. Even tho this answer dipps deep into design aspects, you may go best with designing your application first. Go ahead an create a EER-Diagram, that represents your data-structure. You can have a generic car entity, that is extended by the patrol car and the electric car (and even a fusion car). There are plenty of tools out there, that help you create such a diagram and convert it into an DDL for the database of your choice.
Conclusion
To be concrete, if you realy have to alter the table at runtime, i would recommend going with the second approach and add a default value to it. However, based on the question you asked, i can't realy see you getting far with it. It would mean that you would have an unkown Object that you want to store.
If that is the case, why not create a new Table with the objects name, that holds the fields of the object as columns? That would allow you to have an acces like this (asuming a repository that stores said object):
$object = new TestObject();
repository->store($object);
Upon calling repository->store(), the repository will check if the database has a table called "TestObject" and, if not, create it. If the table was created, it than could proceed to alter it and add the columns. So, the following would use this:
$object = $repository->load("TestObject");
The Repository would now check for the column TestObject and may create a new TestObject at runtime like this:
function load($name) {
$returnValue = new $name;
// Set the fields based on the database entries.
}
It has the big advantage, that you would only have to check, whether or not the table exists and (if yes) create a new Object or (if not) throw an Exception.
Ofcourse this comes with more problems. Error handling is not done here (for example, what happens with namespaces and what happens, if there are more objects with the same name), to keep it simple. But this should bring the point accross.
Sorry for the long post, have a nice day :)
Related
I have a set of model class definitions, each with some properties and methods.
Each new model class definition is mapped to its own database table, the properties forming the table columns. Each newly created object can then be adequately saved for a rainy day.
My question is, how can I elegantly allow for additional properties to be added at runtime, and have it saved without re-migrating all the tables in the database.
For example, say I have an "Article" object with name, creation date and article body as properties (initially), but at runtime a user decides that for a particular article they'd like to add a synopsis as a property, how do I save the new entity to the database?
I guess I'm trying to (amongst other things) mimic adding fields in Drupal or Custom Fields in Wordpress.
As one has to specify the data type of each column when creating or updating a table, the only way I can think of doing this is by creating a column with an array as its data type. This solution feels a bit awkward though, and just wondering how others have done it.
Your help would be much appreciated.
as a lowest common denominator you could persist your objects as a series of key-value pairs, but this sounds clunky and slow. I could also envisage nightmares when you have objects containing objects etc.
Or, you could serialize them before storage (as xml documents, perhaps?) But this forgoes any kind of structure at the database level and would complicate matters if you wished to query the database on specific column values.
But if I were you I'd read up on some "hibernation" utilities e.g. Hibernate (!) to get a feel for how they persist things. These utilities are already solving your exact problem, and you can guarantee they'll have put a fair amount of thought into it.
If you're lucky there may even be such a utility you could use out of the box, without necessarity understanding the nitty gritty.
I'm currently at an impasse in reguards to the structural design of my website. At the moment I'm using objects to simplify the structure of my site (I have a person object, a party object, a position object, etc...) and in theory each of these is a row from it's respective table in the database.
Now from what I've learnt, OO Design is good for keeping things simple and easy to use/implement, which I agree with - it makes my code look so much cleaner and easier to maintain, but what I'm confused about is how I go about linking my objects to the database.
Let's say there is a person page. I create a person object, which equals one mysql query (which is reasonable), but then that person might have multiple positions which I need to fetch and display on a single page.
What I am currently doing is using a method called getPositions from the person object which gets the data from mysql and creates a separate position object for each row, passing in the data as an array. That keeps the queries down to a minimum (2 to a page) but it seems like a horrible implementation and to me, breaks the rules of object orientated design (should I want to change a mysql row, I'd need to change it in multiple places) but the alternative is worse.
In this case the alternative is just getting the ID's that I need and then creating separate positions, passing in the ID which then goes on to getting the row from the database in the constructor. If you have 20 positions per page, it can quickly add up and I've read about how much Wordpress is criticised for it's high number of queries per page and it's CPU usage. The other thing I'll need to consider in this case is sorting, and doing it this way means I'll need to sort the data using PHP, which surely can't be as efficient as natively doing it in mysql.
Of course, pages will be (and can be) cached, but to me, this seems almost like cheating for poorly built applications. In this case, what is the correct solution?
The way you're doing it now is at least on the right track. Having an array in the parent object with references to the children is basically how the data is represented in the database.
I'm not completely sure from your question if you're storing the children as references in the parent's array, but you should be and that's how PHP should store them by default. If you also use a singleton pattern for your objects that are pulled from the database, you should never need to modify multiple objects to change one row as you suggest in your question.
You should probably also create multiple constructors for your objects (using static methods that return new instances) so you can create them from their ID and have them pull the data or just create them from data you already have. The latter case would be used when you're creating children; you can have the parent pull all of the data for its children and create all of them using only one query. Getting a child from its ID will probably be used somewhere else so its good just to have if its needed.
For sorting, you could create additional private (or public if you want) arrays that have the children sorted in a particular way with references to the same objects the main array references.
Currently, I am dealing with database structure and I would like to get a piece of advice.
I have 2 objects: banner and ad.
For them I may create banner table and ad table, which will hold all the info about each entity. As main advantage I see that everything related to 1 entity is in this entity table.
On the other hand, I may some table like:
entity_properties.
It will hold value_id entity_id property value. The main advantage is that for entities I need only some basic fields, other fields can be put in this table.
But I am not sure which is the better practice and performance?
Thanks in advance.
For the sake of normalization it is always better to have 1 table per 1 entity. Normalization is an aim or an approach to minimize redundancy and dependency in relational databases . In your case banner and ad are different entities. For now it seems that you can use them in same table. So "redundancy" is not the case. However, what if you want to add some additional fields later?
In addition code complexity and readability is another issue. For instance, when you add different types of object in same table you need to add an internal logic to differentiate them in your code. This means you have complex and probably less readable code.
That depends on the exact use of your system and the attributes/values you're trying to store.
As I see it, I think it would be good to save the important and required information in one table, your 'ad' table, and the rest in the 'ad_entities' table, with an ad_id, entity_name, entity_value, or something similar for your application.
This is a good performance choice since you'll be able to get all the information about the current Ad or all Ads using just one quite simple query, which your objects can easily figure out.
This isn't much of an issue with MySQL per-se.
The Full Story
I'm writing a very small PHP framework. It isn't like existing frameworks where they force you to use a certain methodology. It isn't either like a CMS framework. Trust me, I've seen Zend framework and I've used CMSes like Joomla and WordPress extensively, none of them come close to what I'm doing.
Introducing The Issues
I'm writing the Database abstraction part. You get class methods like ::table_exists() etc.
It is designed in a way that people can easily add different database classes and use them instead (eg; mysql, mssql, oracle, flatfile...).
They simply need to write a class which satisfies a base abstract classes'.
The Real Issue
I'm writing the functionality for ::table_create(), but have one main problem: MySQL doesn't like empty tables (ie, without a column).
I have several proposed fixes:
For each new table, create a commonly used column, such as 'id' (type=INT)
For each new table, create a temp column which doesn't use any space as much as possible (perhaps a boolean column?)
Somehow delay table creation until at least one column can be created
This approach is most certainly new, and I'd like to here some unbiased comments about it (anything on the lines of "but no one does it that way" won't do).
Well I would either go with option 1), Adding a generic ID column, which you might find you need anyway, or with option 3) Delaying the table creation. I'm assume after they call ::table_create() they will be calling table_add_col(), etc. So just delay creation until there is at least one column, OR until they actually try and use the table for the first time.
Your proposed fixes look quite good. But I would recommen them in a diffrent order. If you are able to delay the creation, tht's probably the best. My second favorite would be to have a table with only an ID, although you might be delete this column, if you want to create a many-to-many relations table with two foreign keys only.
last of your points.
its really very strange what you are doing here. creating tables on the fly? dynamically or something?
well... whatever you are trying to accomplish. you should have a look at document/object oriented databases like couchdb http://couchdb.apache.org/ ! you can create a document and dynamically add whatever fields you want. those are the closest thing to your "columns"
but as you like it...
your first attempt is ugly because it might lead to conflicts.
the second attempt is clumsy. but if you do so create a col with uniqueprefix_random so you can delete it afterwards.
but its well... i dunno what to say about that.
theird approach seems the only senseful!
I have a table called Cat, and an PHP class called Cat. Now I want to make a CatDataMapper class, so that Cat extends CatDataMapper.
I want that Data Mapper class to provide basic functionality for doing ORM, and for creating, editing and deleting Cat.
For that purpose, maybe someone who knows this pattern very well could give me some helpful advice? I feel it would be a little bit too simple to just provide some functions like update(), delete(), save().
I realize a Data Mapper has this problem: First you create the instance of Cat, then initialize all the variables like name, furColor, eyeColor, purrSound, meowSound, attendants, etc.. and after everything is set up, you call the save() function which is inherited from CatDataMapper. This was simple ;)
But now, the real problem: You query the database for cats and get back a plain boring result set with lots of cats data.
PDO features some ORM capability to create Cat instances. Lets say I use that, or lets even say I have a mapDataset() function that takes an associative array. However, as soon as I got my Cat object from a data set, I have redundant data. At the same time, twenty users could pick up the same cat data from the database and edit the cat object, i.e. rename the cat, and save() it, while another user still things about setting another furColor. When all of them save their edits, everything is messed up.
Err... ok, to keep this question really short: What's good practice here?
From DataMapper in PoEA
The Data Mapper is a layer of software
that separates the in-memory objects
from the database. Its responsibility
is to transfer data between the two
and also to isolate them from each
other. With Data Mapper the in-memory
objects needn't know even that there's
a database present; they need no SQL
interface code, and certainly no
knowledge of the database schema. (The
database schema is always ignorant of
the objects that use it.) Since it's a
form of Mapper (473), Data Mapper
itself is even unknown to the domain
layer.
Thus, a Cat should not extend CatDataMapper because that would create an is-a relationship and tie the Cat to the Persistence layer. If you want to be able to handle persistence from your Cats in this way, look into ActiveRecord or any of the other Data Source Architectural Patterns.
You usually use a DataMapper when using a Domain Model. A simple DataMapper would just map a database table to an equivalent in-memory class on a field-to-field basis. However, when the need for a DataMapper arises, you usually won't have such simple relationships. Tables will not map 1:1 to your objects. Instead multiple tables could form into one Object Aggregate and viceversa. Consequently, implementing just CRUD methods, can easily become quite a challenge.
Apart from that, it is one of the more complicated patterns (covers 15 pages in PoEA), often used in combination with the Repository pattern among others. Look into the related questions column on the right side of this page for similar questions.
As for your question about multiple users editing the same Cat, that's a common problem called Concurrency. One solution to that would be locking the row, while someone edits it. But like everything, this can lead to other issues.
If you rely on ORM's like Doctrine or Propel, the basic principle is to create a static class that would get the actual data from the database, (for instance Propel would create CatPeer), and the results retrieved by the Peer class would then be "hydrated" into Cat objects.
The hydration process is the process of converting a "plain boring" MySQL result set into nice objects having getters and setters.
So for a retrieve you'd use something like CatPeer::doSelect(). Then for a new object you'd first instantiate it (or retrieve and instance from the DB):
$cat = new Cat();
The insertion would be as simple as doing: $cat->save(); That'd be equivalent to an insert (or an update if the object already exists in the db... The ORM should know how to do the difference between new and existing objects by using, for instance, the presence ort absence of a primary key).
Implementing a Data Mapper is very hard in PHP < 5.3, since you cannot read/write protected/private fields. You have a few choices when loading and saving the objects:
Use some kind of workaround, like serializing the object, modifying it's string representation, and bringing it back with unserialize
Make all the fields public
Keep them private/protected, and write mutators/accessors for each of them
The first method has the possibility of breaking with a new release, and is very crude hack, the second one is considered a (very) bad practice.
The third option is also considered bad practice, since you should not provide getters/setters for all of your fields, only the ones that need it. Your model gets "damaged" from a pure DDD (domain driven design) perspective, since it contains methods that are only needed because of the persistence mechanism.
It also means that now you have to describe another mapping for the fields -> setter methods, next to the fields -> table columns.
PHP 5.3 introduces the ability to access/change all types of fields, by using reflection:
http://hu2.php.net/manual/en/reflectionproperty.setaccessible.php
With this, you can achieve a true data mapper, because the need to provide mutators for all of the fields has ceased.
PDO features some ORM capability to
create Cat instances. Lets say I use
that, or lets even say I have a
mapDataset() function that takes an
associative array. However, as soon as
I got my Cat object from a data set, I
have redundant data. At the same time,
twenty users could pick up the same
cat data from the database and edit
the cat object, i.e. rename the cat,
and save() it, while another user
still things about setting another
furColor. When all of them save their
edits, everything is messed up.
In order to keep track of the state of data typically and IdentityMap and/or a UnitOfWork would be used keep track of all teh different operations on mapped entities... and the end of the request cycle al the operations would then be performed.
keep the answer short:
You have an instance of Cat. (Maybe it extends CatDbMapper, or Cat3rdpartycatstoreMapper)
You call:
$cats = $cat_model->getBlueEyedCats();
//then you get an array of Cat objects, in the $cats array
Don't know what do you use, you might take a look at some php framework to the better understanding.