0

I need some functionality for dynamic creation table in DB. Algorithm is: 1) register new user -> make record in DB (this is simple) 2) after registration create table like user_data_abcdef123456... where abcdef123456 - is random pregenerated hash. this table must created from (for example) existing default entity (user_data_) Entity:

Path\To\Entity\UserData:
    type: entity
    table: user_data_
....

in Controller do like this:

$doctrine = $this->getDoctrine();

/** @var AbstractSchemaManager $manager */
$manager = $doctrine->getConnection()->getSchemaManager();
/** @var ClassMetadata $metadata */
$metadata = $doctrine->getManager()->getClassMetadata($class);
$metadata->setPrimaryTable(array('name' => $metadata->getTableName() . $project));

$table = new Table($metadata->getTableName());
$manager->createTable($table);

and I need set all column, all index.. etc.

Is there any correct solution?

4
  • 1
    I'm almost sure that this is not a good idea :) What are you trying to achieve by creating table per user. Maybe there is another - better way Commented Apr 2, 2014 at 19:47
  • 1
    This is a good idea :) This is like horizontal sharding per user. In system total count of users is 28 +- tests user, but necessary data per user has a different and big data to stored and analyse with date range period. The hash generated for each period + user as unique value. That is why I need functionality to create unique table on demand. Is any solution exists? :) Commented Apr 3, 2014 at 7:16
  • Of course it exists :) Just keep users in one table, you can keep properties in another one. If users can have wide range different properties you can use dictionary table to keep these different options. In your solution there are a lot of drawbacks. Just imagine how hard would be changing db schema (eg you decide to add new field to a user, like "date of birth"). Another example: you have different table and you want an association to a user - how will you do it with table per user? By creating another 28 tables? Commented Apr 3, 2014 at 17:28
  • The user_data_abcdef123456... is a table-logger events store data table with fields event_name, event_value, event_type, event_date and about 1 000 000 events per day per user income into DB... Than is why we decide to separate tables per users. The reasons are: minus one index, make partition by date only, the table size = (old table size) / (user count) -> search faster, easy move one user data table to separate DB server, etc... Commented Apr 7, 2014 at 8:28

2 Answers 2

3

Hooray! I found solution! Thanks for trevorengstrom in Doctrine automatically create all the database tables answer. The solution is:

    $doctrine = $this->getDoctrine();

    /** @var ObjectManager|EntityManagerInterface $manager */
    $manager = $doctrine->getManager();

    /** @var ClassMetadata $metadata */
    $metadata = $manager->getClassMetadata($class);
    $metadata->setPrimaryTable(array('name' => $metadata->getTableName() . $project));

    $schemaTool = new SchemaTool($manager);
    $schemaTool->createSchema(array($metadata));  

where $class = 'DemoBundle:UserData' and $project = 'abcdef123456...';

Sign up to request clarification or add additional context in comments.

2 Comments

what is $project = 'abcdef123456...' ? Is that just a unique string and could be anything?
Yes, in my case - this is a md5($UniqueProjectName).$UniqueProjectId
0

If you are using Repository (and you should use them) clean way of creating table:

class YourRepository extends EntityRepository
{
public function createTable()
{
    $schemaTool = new SchemaTool($this->getEntityManager());
    $schemaTool->createSchema(
        [$this->getClassMetadata()]
    );    
}

/**
* @param string $entityName Your entity full name like YourEntity::class
*/
public function createTableByEntity($entityName)
{
    $schemaTool = new SchemaTool($this->getEntityManager());
    $schemaTool->createSchema(
        [$this->getEntityManager()->getClassMetadata($entityName)]
    );    
}

}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.