In the broad sense, your architecture sounds over-engineered (over-engineering is not neccessary for a "larger, multi-player game"). You haven't really provided enough specifics for me to comment in turn, so I'll offer some similarly broad suggestions:
- in general, it is better for references to be one-way. That is, a character should know what room it is in, or a room should know about characters in it, but not both unless absolutely necessary. Having both complicates things, both in terms of potential API surface area (both interfaces can answer very similar questions of the current game state) and lifetime management (moving a character involves updating state in two places, so does releasing a character). Duplicate state also leads to fun bugs later in development. If you can do without, do so.
- fight the urge to literally objectify every object in your OO design. Fight the urge to give everything verbs that create as-close-to-1:1 analogues with the real world as possible. Yes, in the real world a character (person) can move itself, but it sounds like in your architecture, the character just passes a message along to something else to actually move it so the existence of the move verb on the character class is questionable.
- when you have trouble thinking about where to put some functionality, consider thinking about how you're going to use it. What state that does that functionality need to do its job, and where do you current have that state? What is involved from getting that state from where it is to where you're thinking about calling this new function, and can you put that function elsewhere -- closer to the state it will tend to use?
- there is no standard formula for constraining state and knowledge of the world across interface boundaries. There are guidelines, though. Prefer writing interfaces that are easy to use properly and efficiently and hard to use improperly, for example. Prefer interfaces that allow the implementation to be as uncomplicated and direct as possible.
- Forget relational databases exist for now. SQL and such is fine for persistent data that you'll need to query in a complex fashion slowly. It is absolutely not a good idea to use one in real-time; stick to data structures in local process memory optimized for the actions you're going to take on them.