Kapitel 6 – Reflektion och jämförelse
1. När använder man vilken databas?
SQLite
Använd när:
- ✅ Du bygger en desktop- eller mobilapp
- ✅ Projektet är litet/prototyp
- ✅ Endast en användare åt gången
- ✅ Du vill ha enkel deployment (en fil)
- ✅ Ingen nätverksåtkomst behövs
Exempel:
- Anteckningsappar
- Lokala inställningar
- Utvecklings-/testdatabaser
- Embedded systems
MySQL
Använd när:
- ✅ Du bygger en webbapplikation
- ✅ Många samtidiga användare
- ✅ Open source är viktigt
- ✅ LAMP-stack (Linux, Apache, MySQL, PHP)
- ✅ Community och plugins är viktigt
Exempel:
- WordPress-sajter
- E-handel
- CMS-system
- Webbforum
SQL Server / LocalDB
Använd när:
- ✅ Du arbetar i Microsoft-ekosystemet
- ✅ Windows-baserade företagssystem
- ✅ Integration med Azure
- ✅ Avancerade features (BI, reporting)
- ✅ Enterprise-support behövs
Exempel:
- Företagsapplikationer
- .NET-baserade system
- Azure-integrationer
- Data warehouse
MongoDB
Använd när:
- ✅ Flexibelt schema behövs
- ✅ JSON/API-baserad data
- ✅ Horisontell skalning är viktigt
- ✅ Hierarkisk data (dokument med subdokument)
- ✅ Snabb iterativ utveckling
Exempel:
- Content management
- Real-time analytics
- IoT-data
- Katalogsystem med varierande produktegenskaper
2. Skillnader mellan SQL och NoSQL
Datamodell
| Aspekt | SQL | NoSQL (MongoDB) |
|---|---|---|
| Struktur | Tabeller, rader, kolumner | Collections, dokument |
| Schema | Fast, definierat i förväg | Flexibelt, kan ändras |
| Relationer | Foreign keys + JOINs | Embedded documents eller referenser |
| Datatyper | Strikta (INT, VARCHAR) | JSON-liknande (String, Number, Array, Object) |
Query-språk
SQL:
SELECT c.Name, o.OrderDate, o.TotalAmount
FROM Customers c
INNER JOIN Orders o ON c.CustomerId = o.CustomerId
WHERE c.City = 'Stockholm'
ORDER BY o.OrderDate DESC;
MongoDB:
db.customers.aggregate([
{
$match: { "address.city": "Stockholm" }
},
{
$lookup: {
from: "orders",
localField: "_id",
foreignField: "customerId",
as: "orders"
}
},
{
$unwind: "$orders"
},
{
$sort: { "orders.orderDate": -1 }
}
])
Men oftast i MongoDB:
// Embedded approach - inga JOINs!
db.customers.find({
"address.city": "Stockholm"
})
Transaktioner
SQL:
- ✅ ACID-garantier (Atomicity, Consistency, Isolation, Durability)
- ✅ Transaktioner över flera tabeller
- ✅ Rollback vid fel
MongoDB:
- ⚠️ ACID på dokumentnivå (MongoDB 4.0+)
- ⚠️ Multi-document transactions finns men används sällan
- ✅ Atomic operations på ett dokument
Skalning
SQL (Vertikal skalning):
Liten server → Större server → Ännu större server
- Begränsad av hårdvara
- Dyrt att skala
NoSQL (Horisontell skalning):
1 server → 3 servrar → 10 servrar → 100 servrar
- Obegränsad skalning (teoretiskt)
- Billigare att lägga till fler “små” servrar
3. Samma app i olika databaser
Låt oss bygga en enkel kundapp i alla fyra databaser!
Exempel: Kundregister med adresser
SQLite / MySQL / SQL Server (identisk kod med EF Core)
Modeller:
public class Customer
{
public int CustomerId { get; set; }
public string Name { get; set; } = string.Empty;
public string Email { get; set; } = string.Empty;
public Address Address { get; set; } = null!;
}
public class Address
{
public int AddressId { get; set; }
public int CustomerId { get; set; }
public string Street { get; set; } = string.Empty;
public string City { get; set; } = string.Empty;
public string Zip { get; set; } = string.Empty;
}
DbContext:
public class AppDbContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Address> Addresses { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
// SQLite
optionsBuilder.UseSqlite("Data Source=app.db");
// MySQL
// optionsBuilder.UseMySql("Server=localhost;Database=myapp;...", ServerVersion.AutoDetect(...));
// SQL Server
// optionsBuilder.UseSqlServer("Server=(localdb)\\MSSQLLocalDB;Database=MyApp;...");
}
}
CRUD:
// CREATE
using (var context = new AppDbContext())
{
var customer = new Customer
{
Name = "Anna",
Email = "anna@example.com",
Address = new Address
{
Street = "Storgatan 1",
City = "Stockholm",
Zip = "11122"
}
};
context.Customers.Add(customer);
context.SaveChanges();
}
// READ
using (var context = new AppDbContext())
{
var customers = context.Customers
.Include(c => c.Address)
.Where(c => c.Address.City == "Stockholm")
.ToList();
}
// UPDATE
using (var context = new AppDbContext())
{
var customer = context.Customers.Find(1);
customer.Email = "newemail@example.com";
context.SaveChanges();
}
// DELETE
using (var context = new AppDbContext())
{
var customer = context.Customers.Find(1);
context.Customers.Remove(customer);
context.SaveChanges();
}
MongoDB (embedded document approach)
Modeller:
public class Customer
{
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
[BsonElement("name")]
public string Name { get; set; } = string.Empty;
[BsonElement("email")]
public string Email { get; set; } = string.Empty;
[BsonElement("address")]
public Address Address { get; set; } = null!;
}
public class Address
{
[BsonElement("street")]
public string Street { get; set; } = string.Empty;
[BsonElement("city")]
public string City { get; set; } = string.Empty;
[BsonElement("zip")]
public string Zip { get; set; } = string.Empty;
}
Anslutning:
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("myapp");
var collection = database.GetCollection<Customer>("customers");
CRUD:
// CREATE
var customer = new Customer
{
Name = "Anna",
Email = "anna@example.com",
Address = new Address
{
Street = "Storgatan 1",
City = "Stockholm",
Zip = "11122"
}
};
await collection.InsertOneAsync(customer);
// READ
var customers = await collection
.Find(c => c.Address.City == "Stockholm")
.ToListAsync();
// UPDATE
var filter = Builders<Customer>.Filter.Eq(c => c.Id, customerId);
var update = Builders<Customer>.Update.Set(c => c.Email, "newemail@example.com");
await collection.UpdateOneAsync(filter, update);
// DELETE
var filter = Builders<Customer>.Filter.Eq(c => c.Id, customerId);
await collection.DeleteOneAsync(filter);
4. Vanliga misstag och lösningar
SQL-databaser
❌ Misstag: Glömma SaveChanges() i EF Core
context.Customers.Add(customer); // Sparas inte!
// context.SaveChanges(); // Behövs!
❌ Misstag: N+1 query problem
foreach (var customer in context.Customers.ToList())
{
Console.WriteLine(customer.Address.City); // En query per kund!
}
✅ Lösning: Använd Include()
var customers = context.Customers.Include(c => c.Address).ToList();
❌ Misstag: SQL injection
string sql = $"SELECT * FROM Users WHERE Username = '{username}'"; // FARLIGT!
✅ Lösning: Parametriserade queries
command.CommandText = "SELECT * FROM Users WHERE Username = @username";
command.Parameters.AddWithValue("@username", username);
MongoDB
❌ Misstag: Försöka använda JOINs
// MongoDB har inte JOINs som SQL!
✅ Lösning: Embedded documents eller $lookup (aggregation)
❌ Misstag: Glömma async/await
var customers = collection.Find(_ => true).ToListAsync(); // Returnerar Task!
✅ Lösning:
var customers = await collection.Find(_ => true).ToListAsync();
❌ Misstag: Fel datatyp för _id
public int Id { get; set; } // MongoDB använder ObjectId!
✅ Lösning:
[BsonId]
[BsonRepresentation(BsonType.ObjectId)]
public string? Id { get; set; }
5. Sammanfattande kommando- och verktygstabell
| Databas | Verktyg | Connection String Exempel | NuGet-paket |
|---|---|---|---|
| SQLite | DB Browser for SQLite | Data Source=app.db | Microsoft.Data.SqliteMicrosoft.EntityFrameworkCore.Sqlite |
| MySQL | phpMyAdmin, MySQL Workbench | Server=localhost;Port=3306;Database=myapp;User=root;Password=pass; | MySql.DataPomelo.EntityFrameworkCore.MySql |
| LocalDB | SSMS | Server=(localdb)\MSSQLLocalDB;Database=MyApp;Integrated Security=true; | Microsoft.Data.SqlClientMicrosoft.EntityFrameworkCore.SqlServer |
| SQL Server | SSMS | Server=localhost,1433;Database=MyApp;User Id=sa;Password=pass; | Microsoft.Data.SqlClientMicrosoft.EntityFrameworkCore.SqlServer |
| MongoDB | MongoDB Compass | mongodb://localhost:27017 | MongoDB.Driver |
Slutsats
Du har nu en komplett överblick över:
✅ Filbaserad databas (SQLite) – enkel, lokal ✅ Klassisk serverdatabas (MySQL) – open source, webben ✅ Microsoft-stacken (LocalDB/SQL Server) – enterprise, .NET ✅ Containeriserad databas (Docker) – modern deployment ✅ Dokumentdatabas (MongoDB) – flexibel, NoSQL
Nästa steg i din databasresa
- Bygg projekt: Skapa samma app i alla databaser för att förstå skillnaderna
- Lär dig optimering: Indexering, query optimization
- Utforska avancerade features:
- Stored procedures (SQL)
- Triggers och views
- Aggregation pipelines (MongoDB)
- Säkerhet: Lär dig om SQL injection, autentisering, kryptering
- Cloud: Utforska Azure SQL, MongoDB Atlas, AWS RDS
Grattis – du har nu kunskapen att välja och använda rätt databas för varje projekt! 🎉