Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Imagine I have multiple companies, which each have multiple employees, multiple vehicles, routes, departures, captured damages and assignments(who has to drive a tour).
How should I structure my Firestore to have it simple and with an overview? The current structure looks a bit like this:
I have multiple collections, which hold all the different companies, all the vehicles, all the employees and so on...
- employees:
- employyeDocuments
- field with companyID (reference to the company document)
- field with employeeID (the uid of that employee, used for identification)
- companies:
- companyDocuments
- array of all the vehicles (each element is a reference to a vehicle in the vehicle collection)
- assignments:
- assignmentDocuments
- field with employeeID
- field with companyID
- field with vehicleID
- field with routeID (all IDs are document references to the according documents)
- routes:
- routeDocuments
- information about the route, waypoints, delivery options... (but NO companyID or employeeID, since that route should be reused and is assigned to an employee in assignments)
- damages:
- damageDocuments
- any recorded damages
There are more collections and documents, but they all follow similar rules, so they don't need to be addressed here. My question is now: Is there any better way to structure this to make it easier to read and avoid accidentally mixing up companies or employees? Or is the approach I use the right one? I am sorrowed about me losing the overview or the database becoming a complete mess.
Education would be great!
Overall, it looks like your structure appears sound but this may be a "many to many" situation and can be addressed in several ways. from experience, keeping it simple but modular has always been key.
Keeping a document with the document name being the UID for that entity is a common tried and tested solution.
simply referencing an id as the field property, an array of id's for the employees in the company, etc.
You should also manage a master employee document by merging all current employee documents into a master document for employers or HR and simply update it with a query for any new employees who may not be on the list.
This restful approach can help reduce maintenance needs and improve performance overall.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am working on a management app for local groups.
The app also displays each group its contacts list.
I wonder how should I design my database?
If I store all users on a root level collection, each time a user opens the contacts list it will read all his group's users' documents. Assuming 1000 contacts groups, for example, adds up to A LOT of reads for a simple task like that.
The same goes for using a subcollection for the group.
Storing the group's contacts in the group's document as a map is not scalable.
And the same goes for using a map in the group's document to index a collection or a subcollection in a denormalized model.
And this is where I'm stuck.
Am I missing something or that these are the options I have and I need to choose between a large number of reads each time a user opens the contacts list and a model designed for limited sized groups?
I think this is a common situation. Many items are related to fewer parent items, and we want to show the parent item's children.
For Firestore, it's recommended that you limit your queries.
For example, if a user wants to see the groups' contact list, that's fine, make a query. But don't show all 1000+ contacts at once. Even Facebook doesn't do that (go to a Facebook group and click on "Members", you'll only be shown a dozen or so, and as you scroll down, more queries are made to show you more.)
Users expect this kind of behavior: lazy loading or pagination.
Documentation for Firestore to limit/paginate queries: limit, paginate
This way, groups can be documents, and contacts can be documents that have an Array field that contains the group-id's they belong to. To display a group's contacts, you can use an "array-contains" query on the contacts collection.
Something like this
contacts (collection)
|
--- {contactId} (document)
|
--- (...contact data...)
|
--- group_membership (array)
|
0--- 'groupId111'
|
1--- 'groupId222'
(For the contacts(col)/contact(doc)/group_membership(field) I'm assuming a contact can belong to multiple groups if this is not the case, the field can be a string instead of an array, but it's safer to make it an array in case you change your mind.)
All I'm getting at here is that your vision for the db structure is fine and common, you don't have to restructure just to avoid querying a thousand contact documents... because you don't have to. You don't have to query 100 times the amount of data that your end-user will actually need.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am beginner on Firebase (and beginner on NoSQL).
I would like to learn the good practices about filtering data.
For example with this simple realtime database:
How you would go about filtering this posts?
Example 1: List all posts (without any filter):
firebase.database().ref('post/').once('value').then((snapshot) => {
});
Example 2: List all posts order by createdAt and limit at 3:
firebase.database().ref('post/').orderByValue('createdAt').limitToLast(3).once('value').then((snapshot) => {
});
Example 3: List all posts order by createdAt, endAt(1605972663986) and limit at 3:
firebase.database().ref('post/').orderByValue('createdAt').endAt(1605972663986).limitToLast(3).once('value').then((snapshot) => {
});
But:
How can I get all posts of user "et6e1AKrhk2GwqjCAKUHK5Bjlgu2" order by "createdAt" and limit at 3 ?
How can I get all posts in category [9, 12] order by "createdAt" ?
How can I get all posts exclude category [2, 4] order by "createdAt" ?
Should I retrieve all the posts and then filter them myself? (is it a good way? if I have 100 millions of posts, what should I do ?)
Sorry If my questions look like stupid but I am 100% beginner and I don't know not yet the goods practice (Currently I have over 1000 messages and I need to filter [with pagination] them based on the current user settings).
Thank you
Firebase charges per document read, so reading 100 million posts at once wouldn’t be a good idea as I’m sure you know.
The query questions you asked seem rather simple and should not be a problem. Firebase does have limitations on queries and you should review all the documentation.
When I started with Firebase I used real-time database initially but eventually switch to Cloud Firestone as I found the querying to be much more powerful using where conditions. (Fire store also has some major limitations: https://firebase.google.com/docs/firestore/query-data/queries#query_limitations )
It may be necessary to add fields to your documents for the sole purpose of filtering and querying. Sometimes it works out where you need to sort data client side, which shouldn’t be a big deal.
I suggest you run tests to ensure you can query all data properly and add fields and ensure the DB fits your needs/research limitations before you dive in too deep! Your DB structure looks good!
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
I'm planning to build a MVP for a real estate system using React and Firebase. I have used SQL databases in the past and hence find it difficult to understand the NoSQL concepts (collections, documents, fields).
Below are the tables I would set up in an SQL database and wanted to know how to set up the fields in Firebase. The front end client should not download irrelevant documents and we should be able to query documents across collections.
For example: What's the property address of a particular household member.
Property
PropCode
Start Date
End Date
Property Type - (House, Unit, Villa)
Property Source - ( Developer, Housing, Self)
Address ( State, Post Code\Zip Code, Suburb, Street)
Tenancy
TenancyID
PropCode - Links to the property table
Tenancy Start Date
Tenancy End Date
Tenancy Type (LongTerm, Short Term)
Household
HHID - The household ID
HHMID - The household member ID. Each member in the household is assigned an ID
FirstName
LastName
DOB
Email
HHM Start Date
HHM End Date
Household-Tenancy - Table to link household with Tenancy
TenancyID
HHID
Thanks
Jag
Well, this question is really having a vast scope and it cannot be entirely covered in one answer.
Here is my try to give you a starting point:
Note: This is for Firebase Firestore (not Realtime Database).
Firebase Firestore Schema (Brief):
In firebase, you have a collection which simply can be said as a bunch of documents. Now, what are documents? Documents are the actual place where your data reside. So for eg., you will have a collection named users which would have all the users' documents (data).
Refer here for more details: Firebase Firestore Model
Your Answer (a try):
Collection-Properties: which would contain all of the properties' documents. Each document would contain data of the property (address, unit etc..). It would also contain the type of the Property (room, house etc.) and the UID (the unique ID of a user in Firebase) of the current tenant (By this you can query for the user using his UID in the Tenants collection). The document would also contain a subcollection- Previous Tenants which would contain the documents with details of the previous tenants.
This would also contain all the demographic details of the properties, (a subcollection is recommended not a separate collection).
NOTE: Firestore document can contain at maximum 1mib, so if there is possibility of exceeding that limit then you can break down the details into subcollections.
Collection- Tenants:
which would contain all the tenants' documents. Each document would contain data of the tenant (name, rent etc) and the document ID of the property in which he is currently living (By which you can query the property). Also, it would contain a subcollection-Previous Properties which would have the details of the previous properties in which he lived.
I'm not quite sure about what you mean by rent statement but if it just means the total rent the tenant has to pay in a week, you can directly have a subcollection which would contain the tenant's weekly rent.
I hope I was able to cover you listed assets. In these cases, no one can say a correct or a wrong data structure. You just need to think of the one, which suits you best.
Additional Bonus: Advanced Data Modeling with Firestore by Example
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
I need a Database to store the following information :
User : FirstName, LastName, Email, Mobile, About/Description, Type (Staff/Freelancer/Client)
Staff : Type (Designer/FE Developer/BE Developer/DB Developer/SE Optimist), Rank of Staff
(Manager/Staff/Employee), Projects worked on, Active Projects working on, Address,
Skills (HTML/CSS/JS/ASPX/PHP/DB Development/SEO/Design),
Software(Photoshop/Illustrator/In-Design/Fireworks/VisualStudio/MSQL/Wordpress)
Freelancer : Type (Designer/FE Developer/BE Developer/DB Developer/SE Optimist), Projects worked on, Active Projects working on, Address, Skills (HTML/CSS/JS/ASPX/PHP/DB Development/SEO/Design), Software (Photoshop/Illustrator/InDesign/Fireworks/VisualStudio/MSQL/Wordpress)
Client : Projects Owned, Active Projects owned, Address (Home/Work/Invoicing/Delivery)
Address : House No:, Street Address, Line 2, Line 3, County, Country, Postcode, Landline
Project : Title, Client Name, Start Date, End Date, Due Date, Status (Active, Hold, NotActive), About, Development Team (List of Freelancers or Staff working on the Project), Progress (done by Milestones : Design/FE/BE/DB/BO/SEO/Deployment)
Basically the thing I'm struggling on is how to link the different type of Address and Users etc. For example a User can be : Staff or a Freelancer or an Client, Or a staff or freelancer can also be a client. I have no idea how that would work in Database Format. The same goes for Address Types etc.
Any Help ? I'm really Stuck. Thanks in Advance.
You're asking about the basics of RDBMS design. It's sometimes called Entity-Relationship design. It's a big topic. You may want to read a book on it.
It sounds like you need a Person table with a row describing each unique person in your system.
You then need, perhaps, an Organization table with a row describing each organization (company, consultancy, freelance entity, customer, provider, etc).
A Person_Organization table could relate persons to organizations. This would implement a many-to-many entity relationship between Person and Organization. This table could contain PersonID, OrganizationID, and a field describing that person's role in that organization.
You could add a Contact table with contact information (addresses, tel nos, email, etc). It would contain a Person id in each row.
You'd have Project table with a row for each project. This would contain an OrganizationID that identified the single customer for it, as well as other material describing the project.
There'd also be a Role table with a role for each Organization playing a role in each project.
How to handle an Organization that has more than one contact address is an exercise left to you.
Please keep in mind that "too clever is dumb" in this kind of work.
You do all of this using the concept of a foreign key.
Generally, a good idea is to give each table a primary key column that will serve as an identifier for each row of data. User table would have UserId, Project table would have ProjectId, etc.
From there, you add foreign key constraints to columns in your other tables that forces those rows to map to a User. For example, your Address table would have a column called UserId that is foreign key to the User table; this key tells you that the address of that row belongs to the corresponding User.
How to build the foreign key constraints depends on your requirements and the relationships between your data; it's something that you should figure out so that you will be able to access all of the necessary information using simple queries.
Also, keep in mind that your data is hierarchical. You have a Client, Freelancer, and Staff, each of which needs an address. But all of these 3 are also users. It makes much more sense to key each of those tables to the User table, and then key the Address table to the User table as well. This allows for your relationships to be more flexible and easier to understand.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 8 years ago.
Improve this question
I'm halfway through coding a basic multi-tenant SaaS ECM solution. Each client has it's own instance of the database / datastore, but the .Net app is single instance. The documents are pretty much read only (i.e. an image archive of tiffs or PDFs)
I've used MSSQL so far, but then started thinking this might be viable in a NoSQL DB (e.g. MongoDB, CouchDB). The basic premise is that it stores documents, each with their own particular indexes. Each tenant can have multiple document types.
e.g. One tenant might have an invoice type, which has Customer ID, Invoice Number and Invoice Date. Another tenant might have an application form, which has Member Number, Application Number, Member Name, and Application Date.
So far I've used the old method which Sharepoint (used?) to use, and created a document table which has int_field_1, int_field_2, date_field_1, date_field_2, etc. Then, I've got a "mapping" table which stores the customer specific index name, and the database field that will map to. I've avoided the key-value pair model in the DB due to volume of documents.
This way, we can support multiple document types in the one table, and get reasonably high performance out of it, and allow for custom document type searches (i.e. user selects a document type, then they're presented with a list of search fields).
However, a NoSQL DB might make this a lot simpler, as I don't need to worry about denormalizing the document. However, I've just got concerns about the rest of the data around a document. We store an "action history" against the document. This tracks views, whether someone emails the document from within the system, and other "future" functionality (e.g. faxing).
We have control over the document load process, so we can manipulate the data however it needs to be to get it in the document store (e.g. assign unique IDs). Users will not be adding in their own documents, so we shouldn't need to worry about ACID compliance, as the documents are relatively static.
So, my questions I guess :
Is a NoSQL DB a good fit
Is MongoDB the best for Asp.Net (I saw Raven and Velocity, but they're still kinda beta)
Can I store a key for each document, and then store the action history in a MSSQL DB with this key? I don't need to do joins, it would be if a person clicks "View History" against a document.
How would performance compare between the two (NoSQL DB vs denormalized "document" table)
Volumes would be up to 200,000 new documents per month for a single tenant. My current scaling plan with the SQL DB involves moving the SQL DB into a cluster when certain thresholds are reached, and then reviewing partitioning and indexing structures.
Answer:
For the document oriented portions, and likely for the whole thing, a nosql solution should work fine.
I've played with, and heard good things about mongodb, and would probably recommend it first for a .net project.
For the document-oriented portion, the performance should be excellent compared to a sql database. for smaller scale, it should be equivalent, but the ability to scale out later will be a huge benefit.