Return User Specific Data from Couchdb - php

background: I have a mysql database that I'm going to move over into couchdb, in that database are some tables, "books", and "users". I login to the web application via a login form and currently post username and password at a php script that then logs the user in and writes a php session to the users table for that user. Now, when the user requests books, I a) make sure that the php session is valid for a user, and then use the logged in userid to get books that user can view.
question: how would you replicate this sort user specific record query in couchdb? I'm assuming the whole point of couchdb is to be able to say, http://somesite.com/couchdb/getBooks/ and that db end point returns books.
maybe i just need to pass a sessionid at the end? http://somesite.com/couchdb/getBooks/?s=123123 BUT then where do I get the session? hmmm.
Any direction or articles that talk about this would be great.

Handling user-specific data in CouchDB is actually a pretty complicated topic, but I tried to summarize some of the different strategies here.
Long story short: if you want to have user-private data in CouchDB (and it sounds like you do), the best way is to have a server-side daemon that allocates one database per user, and the user has full privileges in that database. (This can scale up to > 100k users, so no worries.) Then you just sync that database with PouchDB.
The link above has some third-party projects that implement exactly such a daemon. There's also Janus, which is not ready yet, but once it is, it'll do all of the above as well as integrate nicely with PouchDB.

Related

Most efficient way to track unread messages per user

I am working on a jQuery Mobile Web App where a company will have the ability to message certain groups of users (based on their profile preferences).
I am debating on what is the most efficient way to mark when each user has read the latest messages. I have considered using a session to try and keep track of the last time they opened the messages page, and comparing that to the post times of the messages. I have also considered a table with the message_id and the user_id, marking each one as read when they open the page.
I think both would work, but I am trying to balance the pros and cons. Keeping in a database would allow me to keep a history (especially if i added a timestamp column to know when they read the message), but if it is going to hurt the app performance due to the table size, then it may not be worth it. The app will potentially have 10's of thousands of users.
One thing I should probably mention is that the users may use the app on multiple devices and the app will have very long session times, potentially allowing the user to stay logged in for months. I like the idea that if they read it on one device then it would mark it read on all devices, which may make sessions difficult to work with, right?
Ok, I'm gonna put everything I said in the comments into one solid answer.
Short Answer: You should be using the database to store 'read' notifications
Logic behind it:
It should be a negligable performance hit with decent servers and optimized code (couple of ms max) even with hundreds of thousands of users
It is highly maintainable
You can track it and sync it across devices
Specifically why you shouldn't use sessions
Sessions were designed to store temporary user data (think ram), they're not supposed to log stuff.
You should not be keeping sessions for months. It is highly insecure as it opens up a much larger window for session hijacking. Rather you should be generating a new session each time the app is accessed, and using a different "remember me" cookie or something each time to authenticate them.
Even if you do make your session persist for months, after those months won't the user all of a sudden get a bajillion "unread" notifications?
How to store it in the database
This is called a many-to-many relationship (from the message perspective) OR a one-to-many relationship (from the user perspective)
Table 1: messages
ID, message, timestamp
Table 2: messages_users
ID, user_id, message_id, read
Table 3: users
(Do user business as usual)
I can do one thing, if no problem with one user or 100 of user, you create one column named readUnread with more than 63,999 Characters in which you use put every user your message with 0 and 1 assign like {jeff:0,kevin:1,Sal:0} when read update from 0 to 1 and when you open this on the screen, split it with current user and ";", this will help you (this is the logic which inhance your performance).

Add user registration and subscription to a PHP MySQL web app

I've been working on a web app for a few months now. It's a PHP and MySQL driven database app which relates objects between each other.
I'd like to add functionality so that someone could register to use it and set up a monthly subscription. When they log in the app would simply populate with data from their own database.
I've done some scouring online but I'm struggling to find a starting point for adding this sort of feature.
The app relies on half a dozen tables within a database. So I'm also not sure if creating an individual database per user is practical.
Creating a db per user is very rarely the way to go - it's complicated and has very few benefits with lots of drawbacks (eg maintaining multiple simultaneous Db connections as most libraries only connect to a single Db). What you really need to do is create a user table and then tag various records with a UserId.
When a user registers, create a new User record, then create their new entries in other tables all referencing that Id. (Actually, only the "root" of each relational object needs a UserId eg If you have Order and OrderItems only the Order table needs a UserId)
Without more detail, it's impossible to help further.
Incidentally, the only time you should consider db-per-user is if each user requires unique tables (in which case your app would have to be very complex to actually use the data) or if there are security concerns re: storing data together (more likely with multiple clients than multiple users).

synchronize different user sessions when events happened in PHP

I’m writing a social networking application and I want to synchronize different user sessions.
My context is following:
userA is logged and has an array of his contacts in session.
userB is logged and has an array of his contacts in session.
userA adds userB as a contact.
So, Contact table (DB) sees a new record
And userA has an update of his array of contacts (easy because the event happens on userA navigation side)
My need is following:
I want now to synchronize automatically userB’s session so that his array of contacts is refreshed
without doing a sql query to check the contacts table (db). I want that in order to avoid making too many sql queries to check that.
Do you have any suggestions?
I’m using CodeIgniter (PHP) and the session is managed with database.
Thanks a lot
This is not possible without doing a sql query to check the contacts table. Even if you hold your sessions in sql table you still have to query for the data
You want to update a copy of the data (userAs session) without refering to the master set of data. This is just not going to work.
With it's shared nothing architecture, this is going to be hard to implement in PHP.
The only sensible way to achieve this in anything approaching realtime is to maintain a semaphore for each current user session - and set that semaphore when the session data should be re-loaded. And at that point you must read the data from the database.
Much of this could be done within the session handler - which is probably the most sensible place to handle it - but you need to be aware that the semaphore is therefore volatile and code it appropriately (e.g. using optimistic locking around reading/writing the semaphore).

Multiple user database design

I have to develop a basic social network for an academic purpose; but I need some tips for the users management..
The users are subdivided into 3 groups with different privilege: admins,analysts and standards users.
For every user should be stored into the database the following information: name,lastname,e-mail,age,password.
I'm not quite sure how I should design the database between theese two solutions:
1)one table called 'users' with the 'role' attribute that explain what a user can do and what can't do, and the permissions are managed via php
2)every application user is a database user created with the query 'CREATE ROLE' (It's a postgres database) and he has permissions on some tables granted with the 'GRANT' statement
You should take into account that the project is for a database exam..
thanks
Don't use the database's authorization mechanism to be your application's authorization system. Three main reasons:
A) You'll never be able to change to a different database without rebuilding the whole app.
B) The types of things you want to grant the users in the app might differ from what the db's ACL system allows.
And most importantly:
C) You don't want to give an application user the ability to do anything directly to your database. Ever.
So your #2 option is right out. Thus, store a user type field with each user record, and then "what that user type allows" becomes part of your business logic that is calculated in PHP.
Solution 1 every time as you don't want to restrict yourself to only assign permissions on a per-table basis. Using database users would be cumbersome and not very practical.
Go with Option 1. It will be much more flexible in the long run, probably easier to code, and you don't want to tie your application logic too closely to a specific implementation. What if you later on want to port the application to run on SQL-Server? If database users are implemented differently, Option 2 could give you serious pains.
Go with your first alternative (manage permissions with PHP). Here are the reasons:
The database does not give you enough choices and granularity in the permissions you'll need to manage (who is allowed to send emails, to what groups people are allowed access, etc.)
Typically connections to the database are rather expensive so you'll want to connect once and stay connected as long as possible (with the same database user)
All databases are not created equal in the way they handle user accounts. By building your own user system above SQL you can hope to be more database independant
In the real world the tasks of administering the database and developping programs are done by completely different people and the program does not have the right to create or alter database users

Database and Table Management

I have been creating a web app and am looking to expand. In my web app I have a table for users which includes privileges in order to track whether a user is an administrator, a very small table for a dynamic content section of a page, and a table for tracking "events" on the website.
Being not very experienced with web application creation, I'm not really sure about how professionals would create systems of databases and tables for a web application. In my web app, I plan to add further user settings for each member of the website and even a messaging system. I currently use PHP with a MySQL database that I query for all of my commands, but I would be willing to change any of this if necessary. What would be the best wat to track content such as messages that are interpersonal and also specific user settings for each user. Would I want to have multiple databases at any point? Would I want to have multiple tables for each user, perhaps? Any information on how this is done or should be done would be quite helpful.
I'm sorry about the broadness of the question, but I've been wanting to reform this web app since I feel that my ideas for table usage are not on par with those that experienced programmers have.
Here's my seemingly long, hopefully not too convoluted answer to your question. I think I've covered most, if not all of your queries.
For your web app, you could have a table of users called "Users", settings table called "UserSettings" or something equally as descriptive, and messages in "PrivateMessages" table. Then there could be child tables that store extra data that is required.
User security can be a tricky thing to design and implement. Do you want to do it by groups (if you plan on having many users, making it easier to manage their permissions), or just assign individually due to a small user base? For security alone, you'd end up with 4 tables:
Users
UserSettings
UserGroups
UserAssignedGroups
That way you can have user info, settings, groups they can be assigned to and what they ARE assigned to separated properly. This gives you a decent amount of flexibility and conforms to normalization standards (as mentioned above by DrSAR).
With your messages, don't store them with the username, but rather the User ID. For instance, in your PrivateMessages table, you would have a MessageID, SenderUserID, RecipientUserID, Subject, Body and DateSent to store the most basic info. That way, when a user wants to check their received messages, you can query the table saying:
SELECT * FROM PrivateMessages WHERE RecipientUserID = 123556
A list of tables for your messages could be as such:
PrivateMessages
MessageReplies
The PrivateMessages table can store the parent message, and then the MessageReplies table can store the subsequent replies. You could store it all in one table, but depending on traffic and possibly writing recursive functions to retrieve all messages and replies from one table, a two table approach would be simplest I feel.
If I were you, I'd sit down with a pencil and paper, and write down/draw what I want to track in my database. That way you can then draw links between what you want to store, and see how it will come together. It helps me when I'm trying to visualise things.
For the scope of your web app you don't need multiple databases. You do need, however, multiple tables to store your data efficiently.
For user settings, always use a separate table. You want your "main" users table as lean as possible, since it will be accessed (= searched) every time a user will try to log in. Store IDs, username, password (hashed, of course) and any other field that you need to access when authenticating. Put all the extra information in a separate table. That way your login will only query a smaller table and once the user is authenticated you can use its ID to get all other information from the secondary table(s).
Messages can be trickier because they're a bigger order of magnitude - you might have tens or hundreds for each user. You need to design you table structure based on your application's logic. A table for each user is clearly not a feasible solution, so go for a general messages table but implement procedures to keep it to a manageable size. An example would be "archiving" messages older than X days, which would move them to another table (which works well if your users aren't likely to access their old messages too often). But like I said, it depends on your application.
Good luck!
Along the lines of Cristian Radu's comments: you need to split your data into different tables. The lean user table will (in fact, should) have one unique ID per user. This (unique) key should be repeated in the secondary tables. It will then be called a foreign key. Obviously, you want a key that's unique. If your username can be guaranteed to be unique (i.e. you require user be identified by their email address), then you can use that. If user names are real names (e.g. Firstname Sirname), then you don't have that guarantee and you need to keep a userid which becomes your key. Similarly, the table containing your posts could (but doesn't have to) have a field with unique userids indicating who wrote it etc.
You might want to read a bit about database design and the concept of normalization: (http://dev.mysql.com/tech-resources/articles/intro-to-normalization.html) No need to get bogged down with the n-th form of normalization but it will help you at this stage where you need to figure out the database design.
Good luck and report back ;-)

Categories