Teacher representation in Moodle database - database

I wonder how the instructor is represented in the vast Moodle DB. Where is the specific table with attribute columns to store data for every teacher?
Although there is something relevant like the diagram above, i need something to describe the teacher table.
Any ideas?
picture taken from : http://www.examulator.com/er/

Moodle has the following default archetypes for what you refer to as an instructor;
manager
coursecreator
editingteacher
teacher
A user can be assigned one of these roles in a particular context, a context such as a course or perhaps course category.
The database stores the teacher data across a number of tables. Looking at the database schema diagram you have shown, the tables you are looking for are in the roles grouping. Specifically role and role_assignments. By linking these tables with the user, context and course tables, you can find the staff associated with courses.
An example function to get the staff associated with a particular course would be
function get_course_staff($courseid) {
global $DB;
$sql = "SELECT u.firstname,
u.lastname
FROM {role_assignments} ra
WHERE c.contextlevel = 50 // Numeric value of the course context
AND c.instanceid = ?
AND r.id < 5
JOIN {role} r ON ra.roleid = r.id
JOIN {user} u ON ra.userid = u.id
JOIN {context} c ON ra.contextid = c.id
JOIN {course} co ON c.instanceid = co.id
ORDER BY r.sortorder ASC";
return $DB->get_records_sql($sql, array($courseid));
}
A role can be assigned to many users.
A user can have many roles.
A user is assigned a role in a particular context.

Related

sql server query results based on another resultset

My requirement is like below.
InstituteId is passed as parameter to my query, i need to get all the studentId's who are enrolled in any of the courses the institute is offering and they should be full time students..
There are chances that few users have registered but they are not enrolled in any courses, few users have enrolled on more than 1 course and in this case i need to display this user only once.
SELECT DISTINCT s.StudentId, f.[RegistrationId] from dbo.[Student] s
INNER JOIN dbo.FulltimeStudent f on s.StudentId = f.StundentId
WHERE CourseId in (
SELECT CourseId from dbo.[Institute] WHERE InstituteId = #InstututeId
)
I am seeing some performance lag with the above, I am seeing if there is any better approach to accomplish the above ?

SaaS- Tenant Specific Lookup Data in Shared Database

I am developing multitenant SaaS based application and going with Shared Database for storing all the tenant records with help of TenantId column.
Now the problem is i have some list of lookup records that needs to be shared for all the tenants. For example list of games.
GamesTable
Id
GameName
Also have another table used for storing only tenant specific records
TenantGames
Id
TenantId
GameName
The basic need is i want to use both table data and get the necessary details (Game_Name) while joining with another transaction table like UserGames. How can i achive this with this design? Here Game_Name can be either referred from Games Shared table or TenantSpecificGames table
Is there any other DB design which allows me to do mix both common master data and tenant master data with JOIN?
Basic requirement is keep common data and allow customization for the tenants if they want to add any new items.
This is the design I would then use.
Games
Id
GameName
IsTenantSpecific
SomeGameSpecificColumn
TenantGames
GameId
TenantId
SomeTenantSpecificColumn
AnotherTenantSpecificColumn
Then you can query that table in a Join with:
...
FROM
Games
INNER JOIN UserGames ON
UserGames.GameId = Games.Id
LEFT JOIN TenantGames ON
TenantGames.GameId = Games.Id
WHERE
TenantGames.TenantId = #tenantId OR
(
TenantGames.TenantId IS NULL AND
IsTenantSpecific = 0
)
Game specific fields can be put in the Games table. Tenant specific fields can be added to the TenantGames table, and those fields will be NULL if it is not a tenant specific customization.
We have a saas based database and we keep common data and tenant data in the same table.
Concept
GamesTable
Id NOT NULL
TenantId NULL
GameName NOT NULL
Add a unique key for TenantId and GameName
if TenantId is NULL you know it is common data
if TenantId is NOT NULL you know it belongs to a specific tenant and who exactly.
"Is there any other DB design which allows me to do mix both common
master data and tenant master data with JOIN?"
Yes
SELECT *
FROM GamesTable where TenantId = 'your tenant id'
UNION
SELECT *
FROM GamesTable where TenantId IS NULL -- common
This is a classic example of "many to many".
Table: Games
------------
GameID
GameName
IsMasterGame
TennantGames
------------------
GameID
TennantID
Tennants
------------
TennantID
...
To get the games for a given tennant, you would run a query like:
select *
from Games
where isMasterGame = true
union
select *
from Games g,
TennantGames tg
where g.GameID = tg.GameID
and isMasterGame = false
and tg.TennantID = $currentTennant
(Apologies for archaic join syntax)
The union allows you to ask two questions: which games apply to everyone (isMasterGame = true), and secondly which games apply to the current tennant (tg.TennantID = $currentTennant). Logically, tennant games cannot also be master games.
You can merge the tables leaving TenantId as NULL for records you wish to not be Tenant specific.
Games
Id
TenantId
GameName
The you can query that table in a Join with:
...
FROM
Games
INNER JOIN UserGames ON
UserGames.GameId = Games.Id
WHERE
Games.TenantId = #tenantId OR
Games.TenantId IS NULL
This will save you the trouble of ensuring that the Id is unique between the tables, unless you are using a UNIQUEIDENTIFIER for the Id.

Creating relationships in Microsoft Access

I'm creating a database to track my students' participation in classes. This is what I've set up so far. I'm working in Access 2007.
Participant Master table - name, contact info, enrolled class, enrolled semester. Enrolled class (Class A, Class B, Class C) and enrolled semester (Semester 1, Semester 2) are defined in tables. Primary key is an autoincrement number but students all get a school ID number (ParticipantID).
Query1 pulls name & address for students enrolled in class A, semester 2
(SELECT name, address FROM ParticipantMaster WHERE EnrClass = "Class A" and EnrSem = "Semester 2"). The query works.
DailySessionLog is a table to represent each daily class. Includes fields for date, instructor name (check from list), discusssion topic (check from list).
Now I want to link DailySessionLog to Query1 -- letting me check off every day whether a student was there for None, Partial, Half, or Full session that day. I'm having trouble linking these and creating a subform. Any help?
I tried having a ParticipantID field in DailySessionLog which I linked to ParticipantID in Query1. It doesn't recognize if it's a one:one or :many relationship. If I go ahead and create a subform using the Access wizard it treats the Participant data as the "higher" form and the DailySessionLog data as the "sub" form. I want it to be the other way around.
Thanks for helping!
To create a one-to-one or one-to-many relationship, you should link DailySessionLog to ParticipantMaster rather than to Query1. You would then create a query to show the daily session logs of a given class for a given semester. Example:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = "Class A" AND ParticipantMaster.EnrSem = "Semester 2"
However, it would be better to use variable parameters rather than hard-coded strings. Example:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = [ClassName] AND ParticipantMaster.EnrSem = [SemesterName]
Or, to use a value from a control on an open form:
SELECT {field list} FROM ParticipantMaster INNER JOIN DailySessionLog ON {join expression} WHERE ParticipantMaster.EnrClass = [Forms]![FormName]![ClassControlName] AND ParticipantMaster.EnrSem = [Forms]![FormName]![SemesterControlName]
EDIT
Actually, you want to use this AND xQbert's idea, so, with table names like this for brevity:
Participants (a.k.a. ParticipantMaster)
Sessions (a.k.a DailySessionLog)
ParticipantSession (a.k.a. Participant_daily_session_log)
the first query would be more like this:
SELECT {field list}
FROM
Participants
INNER JOIN ParticipantSession ON Participant.ID = ParticipantSession.ParticipantID
INNER JOIN Sessions ON ParticipantSession.SessionID = Session.ID
Where do you intend the database to "Store" the participation?
I think the problem is you need another table: a Particpiant_Daily_sessioN_log which would store the results of your daily log for each student participation.
Think about the table dailysessionlog you don't want instructor name, topic and date listed for EACH student do you?
So what you have is a many students may attend class and a class may have many students. This means you have a many to many which needs to be resolved before access can figure out what you want to do.
Think of the following tables:
Participant (ParticipantID)
Class (ClassID)
Session (SessionID, ClassID)
ClassParticipants (ClassId, ParticipantID, Semester, year
SessionParticipants (SessionID, ClassID, ParticipantID)

Database design - Friend activities

Currently I am designing a small twitter/facebook kind of system, where in a user should be able to see his friends latest activities.
I am using ASP.NET with MySQL database.
My Friendships table is as follows:
|Friendshipid|friend1|Friend2|confirmed|
Friend1 and Friend2 in the above table are userids.
User activities table design following:
|activityId|userid|activity|Dated|
Now, I am looking for best way to query the latest 50 friend activities for a user.
For example, let's say if Tom logs into the system, he should be able to see latest 50 activities among all his friends.
Any pointers on the best practices, a query or any information is appreciated.
It largely depends on what data is stored in the Friendships table. For example, what order are the Friend1 and Friend2 fields stored in? If, for the fields (friend1, friend2) the tuple (1, 2) exists, will (2, 1) exist also?
If this is not the case, then this should work:
SELECT activities.*
FROM Activities
INNER JOIN Friendships ON userid = friend1 OR userid = friend2
WHERE activity.userid != [my own id]
AND confirmed = TRUE
LIMIT 50;
If you have database performance concern, you may redefine the friendship table as following:
friendshipid, userid, friendid, confirmed
When you query the latest 50 activities, the SQL would be:
SELECT act.*
FROM Activities AS act
INNER JOIN
Friendships AS fs
ON fs.friendid = act.userid
AND fs.user_id = 'logon_user_id'
AND confirmed = TRUE
ORDER BY act.dated DESC
LIMIT 50;
And if there is a index on Friendships(userid) column, it would give the database the chance to optimize the query.
The friendship table redefined needs to create two tuples when a friendship occur, but it still obey the rule of business, and, has performance benefit when you need it.

SQL Server - Nested Query

I have a query that I'm not sure how to write. I'm not a SQL expert and it's pretty nasty. I'm hoping someone here can help me with it.
I have a table called "Members" which has a list of user names to my web site. I need to get the list of users that belong to one or more divisions in my company as well as one or more managers. The specific divisions and managers are chosen by a user in my web site. I have a list of the managers and divisions they have selected. I have also parsed them into a comma-delimited list. Here is a summary of the table information I am trying to link together:
Members
UserName
StoreID
Store
StoreID
PostalCode
Division
PostalCode
ManagerID
Manager
ManagerID
ManagerName
How do I get the list of Members based on a list of Regions and Managers that a user chooses? Sincerely thank you for your help!
Select Members.UserName
From Members
Join Store On Members.StoreID = Store.StoreID
Join Division On Store.PostalCode = Division.PostalCode
Join Manager On Division.ManagerID = Manager.ManagerID
Where Division.PostalCode In (12345, 12346)
And Manager.ManagerID In (1, 2, 3, 4)
You say you have a list of managers and divisions. Do you have ManagerID and PostalCode? If so, you don't need to join in the manager table as both of these are found in the division table.
SELECT
Members.UserName
FROM
Members
INNER JOIN
Store
ON
Members.StoreID = Store.StoreID
INNER JOIN
Division
ON
Store.PostalCode = Division.PostalCode
WHERE
Division.PostalCode IN (Use comma delimited postal codes here)
AND
Division.ManagerID IN (Use comma delimited manager ids here)

Resources