Is To Manually Assign An Entity's IDs A Good Idea? - language-agnostic

We're developing a system to replace an old application from our clients.
Actually there are many entities (like merchants, salesmen, products, etc) that must have a manual assigned ID -so they can be integrated with other existing systems. i.e. accounting.
We think the best solution is simply allow the user to assign the entities IDs manually when the entity is being created; we're going to suggest him the next available ID, and the user will be able to change it if they want. no updates allowed! (muahahaha)
We'll be glad to hear your thoughts about. Pros / Cons
Thanks in advance :)
PD: Do you know any documentation about? -Entities and IDs-
UPDATES
We think there should be cases when this applies and do not. so...
Additionally there are cases when the client literally wants that a given entity has an Id they bring. organization internal codes I think.

Never, ever, ever let the user have access to assign or create the underlying objects identifier. These must be system maintained.
Imagine the nightmare of trying to figure out which entity a related entity actually goes with in the event that the user picks an id that is already in use.
Instead, you should have a regular entity ID of some type (int, guid, whatever) that the system assigns and uses for links to all dependent objects. Then have an "external" id of some sort that the user can put their own identifier in.
Maybe that relates to an external system in some way, maybe not. Point is, you'll be able to maintain your own consistency regardless of what they do.

What is usually done is to specify your own, usually hidden, identifier that is used internally. Then create a second identifier that the user can use as a separate data field. Also, you can get into a bit of a concurrency trouble if you try to suggest the next ID.

I guess this boils down to a separation of concern issues. If you've been developing apps for more than a year you should already know why you need an object identifier in your rdb's, if your users need to concern themselves with assigning and/or managing your underlying object identifiers then you have a design problem, and this problem is that you are mixing data access/storage concerns with business logic. As others already said the best approach is to have two identifiers, one that is transparent to the user and used internally in your app and the other to be used in your integration processes.
I've seen a similar case while working with retailers, there's an id and a product's SKU, the sku itself could be the id yet to allow for a good design we have both.

Related

Alias in Django ORM

I recently started working on a long-running MySQL-backed Django website. The code is mostly clean and well-written except for one patch in the database that seems to have been hurriedly applied.
Specifically, one of the Models was named tbl_Badge_data. As per the naming conventions applied to the rest of the website, this Model should be named Badge.
Unfortunately, there has already been too much built upon the wrong name, and it is infeasible to change the existing scripts (these include Django queryset operations as well as SQL statements). Replacing all instances of the wrong name is not possible, as not all code is owned by us; there are other users relying on this data.
Is there any way to alias Badge to tbl_Badge_data so that all future development uses the correct name? If yes, how will this impact the name of the underlying table? If not, what is the best way to handle something like this without introducing a performance hit (e.g. a "proxy table" or "proxy model" which is a one-to-one map)? As you can imagine, my team doesn't want to invest time in this non-issue (and probably justifiably) want me to ignore this.
A proxy model is not a one-to-one map; it has no representation in the database, and does exactly what you want.
Even simpler though is just to define an alias in your models; after the definition of tbl_Badge_data, you can just do:
Badge = tbl_Badge_data
and import Badge wherever you need it.

User Restrictions based on Field Content in MS Access

I need to set up user permissions within the same table, based on the value of a field. I know that this is not directly possible in Access but a post on Allenbrown.com points to a way of doing this see here. I'm not proficient in coding so I'm hoping that I can get some directions from you. Here are the details:
I have two tables in the database, a parent one populated via a form and a children one populated via a subform. The parent contains companies and the child contain subsidiaries of those companies. In the child table, I have a field called "Domicile" and I want to discriminate user access based on that. Because the database will be used by a variety of people worldwide, my plan is to create user groups based on location and allow users to edit (or add) information based on a match between their location (as specified in the group) and the domicile of the subsidiary. For example, a person in Europe will only be allowed to edit data for subsidiaries that are in Europe, even though companies from other domiciles may be stored in the same table.
I'm looking for some guidance here as well as suggestions as to how you think may be done most effectively. I'm not partial to this method, that's just something I came up with to put some logic behind what I'm doing.
Thank you so much!
The important thing to note in Allen's description is (emphasis mine):
Assuming all updates are performed through forms, the Current event of the form then locks the fields based on this property.
There would be no practical, bulletproof way to prevent users from viewing and altering any data in the table(s) if they open the back-end database file directly.
Since you are asking for advice on how "[row- or column-level restrictions] may be done most effectively" the first issue you need to address is how "effective" those restrictions really need to be:
If you can accept that these will be "soft restrictions" (really a matter of convenience to the user so they don't accidentally alter certain records or fields while using the forms), then Allen's approach might be sufficient. (If so, then follow Allen's instructions as best you can and ask new question if you need help with a specific aspect of that implementation.)
On the other hand, if you need "hard restrictions" (serious protection against mischievous or malevolent user activity) then you'll have to employ a different database back-end -- something like Microsoft SQL Server -- with a richer set of security tools for you to use.

User Access management in mysql/php web page

I am making a semi-simple web application for my mother using php, mysql, and javascript.
She is a teacher, and this wil allow her to manage various components of her lesson plans.
For each component there is a table, and for each component that can contain another component there is another table that holds the relationship. (That table type has two columns each has a foreign key to the related tables)
I am nearly done, but she now wants to allow her friends to use this, I don't care too much about sql injection, but I would like to implement User Control so that only users that create a component can view and edit that component.
I also want them to be able to make public components, so that users can copy components to their own dataset.
My question To implement the user control should I have each user have there own database instant, or should each table have an owner column and column for public/private status, or is there another alternative that I have not thought of.
An issue that I see is that it would require additional mysql query when creating the relations between components because I would need to check that both components user tag matches the current user.
Any feedback/suggestions are helpful
Update The only people using/accessing this will be other teachers, that will be developing their own lesson plans
I would certainly implement this within the same database. Having a different database for each user is not a good solution in this case. Think, for example, how you would build a search function if each user's data is in a separate database will clashing UIDs. It would be a nightmare. Separate databases work where each database serves a separate application and there are precisely zero relations between the data in different databases.
So that brings you on to how to implement it. This will depend on your model. Will each lesson plan only ever have, for example, one and only one owner? If so, then adding that info to the components table might work. Or else you might need a separate table to define ownership and hence access to the different components. Either way, I would make sure the access logic is decoupled and encapsulated in your application to make sure you can change it in the future. Imagine for example you start with a simple, single-owner model but the site grows and grows and soon groups of people all need ownership/edit access to components.

Advice on mixing MongoDB w/ MySQL for a web application

I have a web application that uses a relational database (MySQL). We're adding a new feature that will allow certain users to dynamically construct 'forms' from a pool of optional form elements and distribute these forms for completion/submission to other users.
The problem lies in storing the completed form submissions. Each form can and will vary in the number and combination of form elements, and with a relational database my options are somewhat limited to dynamically creating a new table to hold the submissions of each form (seems like a bad path to go down) or storing each of the submitted forms as JSON in a TEXT column (losing all useful querying abilities of RDBMSs)
I've never actually used MongoDB in a production project before, but I'm thinking it might be a good idea to use my MySQL relational database to store all the forms created by certain users of my application, and then store all the submissions in MongoDB with each document referencing the UUID of the form in MySQL.
The first disadvantage I can think of with this approach is there's no referential integrity between form submissions and the forms located in MySQL. If I delete a form in MySQL, all of the form submissions will have to be manually deleted (if I want to replicate the 'Cascade' effect)
Would I store all of my form submissions for all of my forms in a single MongoDB collection as individual documents? Any advice is greatly appreciated. :)
EDIT 1
Based on the documentation here: http://www.mongodb.org/display/DOCS/Using+a+Large+Number+of+Collections
I'm now considering creating a new collection to hold all the submissions from each unique form type.
EDIT 2
After some careful consideration and the advice of others I've decided to abandon my dual-database approach to solving this problem in favor of a relational-database schema that I think solves the problem of creating dynamic forms and saving the form submissions in such a way that they're easily query-able for complex reporting.
Essentially every record in 'forms' represents a unique form that was built by a user. 'forms_fields' has a foreign key that references the form and an enum-type with the options:
1. checkbox
2. textfield
3. textarea
4. select
5. multi-select
6. date
'forms_fields_options' contains all of the 'options' a select field would have.
With these three tables, users can create customized forms.
When another user fills out & submits the form, a record is created in forms_submissions. For each field, a corresponding record will be created in 'forms_submissions_fields' that references the form submission and the forms_fields_id. The final table, 'forms_submissions_options_multiselect' is essentially a join-table to indicate which options from a multi-select form field the user selected.
A colleague of mine recently lead a webinar on just this subject, titled "Hybrid Applications with MongoDB and RDBMS". You can view it here:
http://www.10gen.com/events/hybrid-applications
From the comments, it looks as though you have already decided to go the RDBMS route, but hopefully this can give you some ideas for a future project, or be beneficial to someone else reading this thread.
Good luck with your application!
This can definitely be done in SQL using EAV. So NoSQL is definitely not required.
Using a tool like MongoDB could be a good fit for the flexible results you want to save, however, there are some trade-offs here, but they may not be exactly what you're expecting.
... storing each of the submitted forms as JSON in a TEXT column (losing all useful querying abilities of RDBMSs)
How many form submissions are you planning to have? What type of querying are you planning to do?
My experience with MongoDB is that it performs very poorly when you're querying against data that is not indexed. In addition, aggregation is generally done in batches using Map/Reduce (or the new Aggregation Framework).
If you compare the complexity of doing roll-ups or the efficiency of doing queries, it's not clear that MongoDB is significantly better here than EAV.
If I delete a form in MySQL, all of the form submissions will have to be manually deleted
Oddly, I have rarely seen this as a problem as you will probably never delete the form in SQL. you will likely do a logical delete and never really remove anything. So this is probably a moot point.
Would I store all of my form submissions for all of my forms in a single MongoDB collection as individual documents?
Again depends on how many forms and submissions you're planning to get. If you have lots of both, then using a collection / submission is going to be very difficult to shard later on.
Honestly, I would use a single collection and then override the _id field to something that can reasonably be used as a shard key. There are some fancy tricks you can play here, but that's beyond the scope of this little write-up.
Summary
End of the day, you can definitely use MongoDB for this problem, but it's not a "home run". If you are unfamiliar with MongoDB, this is definitely a fair "learning project", but expect to hit some roadblocks around querying and aggregation.
I think you're overlooking the fact that an RDBMS will allow things like EAV (Entity-Attribute-Value, which is horrid if you overuse it, but can be great in moderation) or join tables, to construct multiple ordered relations from a single form to various form elements.
I'm not suggesting that an RDBMS is perfect for everything, or even your situation, but I know I have had to build similar systems and have never had to go noSQL to support them in a reasonable way.
Edit: More to the point... storing actual field values puts you one more relation out from the original form elements, but if your UI keeps things consistent you can do this generically. I'd say looking further into which noSQL solutions allow the particular kinds of value-based querying you need might shed more light on your options.

Linq 2 Sql and Dynamic table schemas

First a background. Our application is built on ASP.NET MVC3, .NET 4.0, and uses Linq-to-Sql (PLINQO) as its primary means of data access. Our web application is a multi-tenant/multi-client system where each client gets their own Sql Server database. Each Sql Server database up to now has had exactly the same schema.
Often times, clients will ask us to track custom fields in their Db that other clients don't track. The way we've handled this is by reserving a number of customfields in the db in our main tables. For example, our Widget table may have a CustomText1, CustomText2.. CustomText10, and a CustomDate1, CustomDate2..CustomDate10 fields. Again, all our schemas across clients are the same, so Linq-to-Sql handles these fields just as easily as any other field.
Now we are running into an issue where a client wants several hundred CustomBool fields, but doesn't need the others. So, basically, we are researching for ways to still use the Linq-to-Sql, but have it work against potentially different schemas depending on the database it is connected to (although they are different in a very specific way.)
Too much code has already been built on Linq-to-Sql and accessing the Widget classes generated by it that I'd like to not just fall back to straight SQL.
I've seen answers here and on the web on ways for Linq to Sql to access different tables that have the same schema, but I have not found a good answer to the same table name across different dbs with different columns.
Is this possible?
If the main objective is to store a few extra fields for existing domain objects then why not create a generic table that can store key value pairs. This is extremely flexible since there is no need to change your schema if a customer requires a new property.
We do this frequently and normally have some helpers to correctly cast the properties e.g.
Service.GetProperty<bool>("SomeCustomProperty")
If you are looking for a more "pluggable" domain model that can be completely different for each tenant, I think you will struggle if you are following a database driven approach and using the L2S designer to generate your code.
To achieve this you really need to be generating your database based on your code (domain driven design) which will give you much more flexibility i.e. you can load a tenant specific configuration (set of classes, business rules etc.) at runtime and use this to generate/validate your schema.
Update
It would be good if you could elaborate on exactly what design approach you have taken i.e. are you using the Linq designer and generating your model from the database?
It's clear that a generic key value pair store is not going to meet your querying requirements.
It's hard to provide a solution without suggesting a different technology. Relational SQL databases aren't really suited for dynamic domain models. You may be better off with a document database such as MongoDb or RavenDb where you are not tied to a specific schema. You could even make use of these just for your custom properties.
If that's not ideal then another solution would be to use something like Dapper to construct your queries. Assuming you are developing against interfaces you can have a implementation of your data service per tenant that makes use of their custom fields.
Ayende did a whole series of posts on Multitenancy and covers tenant specific domain models. It starts here and may be of some use to you.