SQL Datenbank – Primärschlüssel und Fremdschlüssel

Wenn man nicht oft mit Datenbanken in Berührung kommt, kann man schnell man wieder was vergessen oder verwechseln. Speziell beim Datenbank Schema Design, sind das wichtige Einstellungen. Man kann zum Beispiel die Datenbankabfrageperformance mit Fremdschlüssel enorm verbessern. Kleiner Hinweis vorweg, auch mit der richtigen Datenbanktyp (IMAP, InnoDB) lässt sich einiges rausholen.

Der wichtigste Satz, den ihr Euch merken müsst. Ein Primärschlüssel ist ein Attribute, womit man eine Datenbankzeile (Tupel) identifizieren kann. Ein Fremdschlüssel ist ein Attribute was auf den Primärschlüssel einer anderen Tabelle verweist und verknüpft diese auch.

Primärschlüssel erkennt man in Tabellen daran das das Attribute Unterstrichen ist.

Fremdschlüssel erkennt man in Tabellen daran das das Attribute Überstrichen ist.

Ein Primärschlüssel muss eindeutig und minimal sein. Also vermeidet gleich, zusammengesetzte Schlüssel als Primärschlüssel und setzt gleich eine ID die sich autoinkrementiert. Klar es gibt immer wieder Fälle, wo man bereits im Vorfeld weiß, dass der Primärschlüssel eindeutig sein wird. Gutes Beispiel Automarken, Wochentage, Schulfächer. Weil es halt nur ein Porsche, ein Freitag und ein Mathe gibt. Dann muss man nicht zwingend mit einer Integer ID die sich autoinkrementiert arbeiten. Ich tue es aber trotzdem. Man weiß ja nie, oder? So kann es ja sein und so war es bereits schon mal, dass ein Autokonzern seinen Namen änderte. Dann müsste man alle Einträge ändern. Mit der Integer ID muss man nur einen Wert aktualisieren.

Domain in Apache2 Server hinzufügen – Virtual Host in Ubuntu

Wer lokal entwickelt, wird es kennen: localhost, localhost:8080, 127.0.0.1, 127.0.0.1:8000 usw. Wer ein wenig Abwechslung benötigt und seine lokalen Projekte über eine Domain im Browser aufrufen möchte kann es ganz einfach umsetzen. Ansonsten ist gegen localhost überhaupt nichts auszusetzen! Ich gehe wieder von unixoiden Betriebssystem aus. In diesem und meinem Fall Ubuntu 18.04.

Falls Ihr noch kein Apache2 am laufen habt, dann könnt Ihr mit folgenden Commands das tun:

sudo apt update
sudo apt upgrade
sudo apt install apache2

Ziel soll es sein ein lokalen Ordner über eine Domain (http://testshop.com) anzusprechen, statt zum Beispiel über http://localhost/testshop.com/public.

Wir legen den Ordner wie folgt an:

cd ~
sudo mkdir /var/www/testshop.dev

Jetzt ändern wir die Rechte mit chown:

sudo chown -R www-data:www-data /var/www/testshop.dev

Nun erstellen wir eine neue Apache Sites Konfigurationsdatei:

sudo nano /etc/apache2/sites-available/testshop.com.conf

In dieser kopieren wir folgenden Inhalt:

<VirtualHost testshop.dev:80>
    ServerAdmin admin@testshop.com
    ServerName testshop.com
    ServerAlias www.testshop.com
    DocumentRoot /var/www/testshop.com
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

<Directory /var/www/testshop.com/>
    AllowOverride All
</Directory>

Die Einträge haben folgende Bedeutungen:

  • ServerAdmin: Hier legt man den Kontakt zum Seitenadmin fest, der bei einem Fehler mit dem Webserver dem Nutzer angezeigt wird. Somit können theoretisch Besucher den Fehler melden.
  • ServerName: Die Domain die wir ansprechen wollen. Mit dem Aufrufe von http://testshop.com werden dann die Date des DocumentRoot verwendet.
  • ServerAlias: Ist der alternative Domainnamen. Somit können wir unsere Seite auch mit www.testshop.com aufrufen.
  • DocumentRoot:  Verzeichnis, dass die Daten für diese Domain beinhaltet.
  • ErrorLog & CustomLog: Fehler-Log-Datei und Aufruf-Log-Datei für diese Domain.

Nun aktivieren wir unsere neue Domainkonfiguration mit:

sudo a2ensite testshop.com.conf

und starten den Server neu:

sudo systemctl reload apache2

Kleiner Tipp! Um die Domain wieder zu deaktivieren, dann folgenden Command nutzen:

sudo a2dissite testshop.com.conf

Falls das noch nicht funktioniert, dann kurz mal:

sudo nano /etc/hosts

aufrufen und testshop.com

127.0.0.1   localhost
111.111.111.111 testshop.com 

eintragen bzw. hinzufügen.

Und ab sofort könnt ihr mit testshop.com euer Projekt im Browser bestaunen und das auch noch offline. (ok, wenn ihr die Styles und Javascripte von einen CDN lädt, stimmt das nur so halb 😉

Greetz aus dem Sauerland

Laravel Mail

Fast jede moderne Webanwendung besitzt ein Emailversand. Laravel macht es dem Entwickler hier sehr einfach.

In unserem Beispiel werden wir eine Bestellbestätigung an den Kunden senden. Als erstes erstellen wir einen Mail Anwendungsfall. In unserem Beispiel wird das eine Bestellbestätigung sein. Das machen wir über die Konsole:

php artisan make:mail OrderConfirmationMail -m emails.order_confirmation

Mit diesem Artisan Command erzeugt Laravel einen neuen Ordner “Mail” in unser Laravel Root Verzeichnis. Dort finden wird nun die Klasse OrderConfirmationMail und im View Order im Verzeichnis Emails (ressources/views/emails/order_confirmation.blade.php) das blade Template.

Weiter werden ich Euch zeigen, wie man die Mailausgabe erst mal zu Testzwecken im Browser sich anzeigen lässt. Es ginge natürlich hier auch sich die Mails alle an sein Postfach schicken zu lassen. Beides geht aber zum Entwickeln ist es schon besser die Mails vorerst im Browser ausgeben zu lassen. In Laravel ist das sehr simpel. Der Parameter -m beim artisan Command eben, ist der entscheidene Punkt um die Browserausgabe zu erzeugen. M steht für Markdown und erstellt in der OrderConfirmation Class in der Methode build() den Return Wert über die Markdown Funktion. Ansonsten würden wir die Laravel Fehlermeldung: “No hint path defined for [mail].” erhalten.

public function build()
{
      	// Also das wird mit -m generiert
	return $this→markdown('emails.order_confirmation');

	// ...und das ohne Markdown Parameter (-m)
       	return $this->view('emails.order_confirmation');
}

Es gibt hier zwei Varianten der Herangehensweise. Einmal über den Controller und die andere über den Router. Zuerst regeln wir es über den Router.

Erste Variante: Über den Router
Dafür gehen wir in unser Router web.php und fügen folgenden Code ein:

use App\Mail\OrderConfirmationMail;
...
Route::get(“/email”, function() {
	return new OrderConfirmationMail();
});
...

Im Browser können wir nun uns die Mail unter http://localhost:8080/email mal anzeigen lassen:

Aber wir wollen doch eine Email verschicken?

Klar, dass geht genauso leicht. Im Router modifizieren wir unser Route wie folgt:

Route::get(“/email”, function() {
	return new OrderConfirmationMail();
});

…und ergänzen unseren Bibliothekenimport noch mit:

use Illuminate\Support\Facades\Mail;

Die zweite Variante: Über den Controller

Sobald eine Bestellung eingegangen und in der Datenbank hinterlegt worden ist, soll an den Kunden eine Bestätigungsmail verschickt werden.

Im OrderController können wir in der store Methode mit folgende Zeilen den Mailversand antriggern:

return \Mail::to("hallo@meine.mail")        
->send(new OrderConfirmationMail());

Achtet hier bitte drauf das Ihr die OrderConfirmationMail für die OrderController verfügbar macht. Also:

use App\Mail\OrderConfirmationMail;

Theoretisch müsstet Ihr auch die Mail Facade reinholen. Aber wenn Ihr die Schreibweise: “\Mail::to(…“ wählt, ist sie somit auch verfügbar. Ansonsten: use Illuminate\Support\Facades\Mail; . Ist Geschmacksache oder Bequemlichkeit. Allerdings solltet Ihr einen Stil konsequent durchziehen und Sprünge vermeiden. Der Konsistenz halber.

Laravel Mail Kofiguration

Wichtig zu erwähnen ist, dass man bevor man eine Mail versendet, den Mailserver in Laravel richtig konfiguriert. Ich habe es über die .env datei vorgenommen und versende meine Mails über smtp.

MAIL_DRIVER=smtp
MAIL_HOST=mein.server.com
MAIL_PORT=25
MAIL_USERNAME=989123
MAIL_PASSWORD=password
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=hallo@meinemail.de

Man kann nun auch im Controller bzw. Router beim Mail Klassen Aufruf Parameter übergeben und somit beim Aufruf einige Konfigurationen vornehmen. Zum Beispiel: CC, BCC hinzufügen.

Mails mit Daten füttern

Um jetzt personalisierte Mails zu versenden, können wir der Mailklasse einen Parameter mitgeben.

Im Controller

// Daten holen
$data = $this->getOrderDataFromDatabaseByOrderId($id);    

// Mail versenden    
return \Mail::to("hallo@meinemail.de")        
->send(new OrderConfirmationMail($data));

In der OrderMailClass

// in der methode build():
return $this->subject('Shop Bestellbestätigung')
→markdown('emails.order_confirmation');

// im Klassenkonstruktor
__constructor($data) {
	$this→data = $data;

Die neue Membervariable $this→data ist nun auch in der View mit $data ansprechbar. Wenn sie ein Array ist dann mit $data[“key”] oder falls es ein Objekt ist mit $data→key.

Laravel Api sagt: Access-Control-Allow-Origin Problem

Gefühlt bei jedem neuen Webprojekt bzw. Apiprojekt bekommt man diesen Fehler und man reißt die Armen hoch zur Decke und ruft: “Warum immer ich? Wieso vergesse ich das immer wieder und was muss ich jetzt machen”. Wahrscheinlich ist es Euch eben so gerade passiert?

Als Autor dieses Textes sag ich: “Nicht schlimm. Passiert vielen und es ist ganz einfach”. Folge dieser Anleitung:

Schritt 1
Erstelle eine neue Middleware mit:

php artisan make:middleware Cors

Schritt 2
Gehe zur neuen Middleware und ändere den Rückgabewert der handle Methode wie folgt ab:

public function handle($request, Closure $next)
{
return $next($request)
	->header('Access-Control-Allow-Origin', "*")
	->header('Access-Controll-Allow-Methods', "GET, POST")
	->header('Access-Controll-Allow-Headers', "Accept,Authorization,Content-Type");
}

Schritt 3
Füge in der protected membervariablen $middleware in der Kernel.php die neuen Cors Middleware ein:

protected $middleware = [
	\App\Http\Middleware\TrustProxies::class,
	\Fruitcake\Cors\HandleCors::class,
	\App\Http\Middleware\CheckForMaintenanceMode::class,
	\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
	\App\Http\Middleware\TrimStrings::class,
	\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
	\App\Http\Middleware\Cors::class,
];

und das wars.

Erklärung

Die neu erstellte Middleware wird nun durch das Einhängen im Kernel bei jedem Request mit aufgerufen. Das bewirkt, dass der Response header mit den Header Attributen : Access-Control-Origin, -Methods und -Headers modifiziert mitgeschickt werden. Somit weiß der Clientbrowser: “keine Panik, alles im grünen Bereich. Der und wir dürfen das”.

Gitignore nachträglich ins Repository hinzufügen

Der Artikel geht davon aus, dass ihr wisst was eine Versionsverwaltungssoftware ist. Ihr solltet auch die Git Grundbefehle wie init, add, commit kennen. Was immer wieder mal, auch bei Erfahrenden Codern, vorkommt ist das kleine .gitignore Chaos. Stellt Euch vor ihr habt bereits euer Initialcommit auf euer Repository gepusht. Dann stellt ihr fest: „Mist in meinem Projekt-Root Verzeichnis liegt ja meine devnotes.txt! Mit den ssh Zugängen und meinen Arztterminen, weil ich zu faul war das mir in mein Kalender zu hacken. Nicht schon wieder! f*c*!“ Wenn ihr wüsstet, was manche Entwickler so alles in ihrer Todolisten schreiben.

Nun haben wir augenscheinlich erst mal ein Problem. Aber das ist schnell gelöst.

Schritt 1: .gitignore Datei anlegen

Falls noch nicht geschehen, legt mit touch .gitignore im Projektroot die neue Datei an. Öffnet diese und schreibt die gewünschten Dateien oder auch Verzeichnisse rein, die zukünftig nichts mehr ins Repository gepusht werden sollen. In dem fiktiven Beispiel wäre es dann devnotes.txt.

#! das gehört in eure .gitignore Datei rein
# ignore theses files
devnotes.txt
# ignore theses folders
node_modules/

Dann erst mal:

git add . && git commit -m”added gitignore”
git push origin master

Wenn ihr im Team arbeitet müsst ihr vom Repro erst mal pullen. Allerdings muss dir hier dann bewusst sein, dass nun sehr wahrscheinlich dein Team deine Einkaufsliste kennt.

Schritt 2: Lösche die zu ignorierende Datei aus dem Repository

Jetzt haben wir eine gitignore die unsere devnotes.txt nicht mehr berücksichtigt. Aber das Problem ist hier noch nicht ganz gelöst. Ihr müsst nun die devnotes.txt aus dem Repository entfernen. Das machen wir mit:

git rm --cached devnotes
git commit -m”remove devnotes from repository ;-)”
git push origin master

Ein Fallstrick hier wäre die Commit Message. Diese verrät anderen nun, dass im Repository deine devnotes.txt liegen. Vielleicht sollte eure Commit-Message in diesem Fall etwas kryptischer ausfallen als sonst.

Ansonsten wäre wir nun hiermit durch und Problem gelöst.

Laravel Foreign Key – Fremdschlüssel anlegen

Es ist wichtig zu verstehen, was das Konzept hinter einem Fremdschlüssel ist. Es ist kein Hexenwerk. Im Gegenteil es ist super simpel, aber manche wollen es nicht verstehen. Fremdschlüssel sind Bindeglieder zwischen Tabellen, die zeigen, dass die Daten zusammengehören obwohl sie in zwei unterschiedlichen Tabellen liegen.

Wir haben zwei Tabellen. Einmal eine Customers Tabelle (id, name, mail) und eine Orders Tabelle (id, customer_id, status). In beiden Tabellen soll die id ein Primärschlüssel sein. Ein Primärschlüssel ist einzigartig (unique) sowie kurz. Kurz weil es auch zusammengesetzte Primärschlüssel geben kann, die sehr lang werden können. Um das zu vermeiden, ist es am besten mit einem Integer der sich selbst inkrementiert zu arbeiten. Das ist quasi Standard.

Datenbank Relation zwischen Customers und Orders über Fremdschlüssel

Nun legen wir den Fremdschlüssel in Tabelle Orders auf customer_id. Somit wären die beiden Tabellen über die customer_id Verknüpft. Das erscheint auf dem ersten Blick als unnötig. Aber bei größeren Datenmengen oder komplexeren SQL Abfragen, wirkt sich der FK positiv und sehr erheblich auf die Abfragegeschwindigkeit aus.

Wie gehen wir in Laravel vor?

Als erstes legen wir die zwei Tabellen Customers und Orders an. Dazu bedien wir uns dem Laravel Komandozeilen Comand artisan.

php artisan make:migration create_customers_table
php artisan make:migration create_orders_table

Dann gehen wir zu den zwei neu angelegten Migrations PHP Dateien. Diese findest Du im Ordner: Database/Migrations. Die aktuelle Namenskovention der Migrationbs Dateien ist:

2020_06_10_114815_create_customers_table (YYYY_MM_DD_iiiiii_add_{name_name}_table)

In einer neu angelegten Migrations findest Du immer die zwei Methoden up und down. Hier die Customers.

...
public function up()
{
        Schema::create('customers', function (Blueprint $table) {
            #$table->id();
            $table->increments("id");            
            $table->string('name',20);
            $table->string('email',20);
}

public function down()
{
     Schema::dropIfExists('customers');
}

Nun legen wir eine neue Migrations Datei an. Und nennen diese ForeignKeys. Und statt create machen wir ein add.

php artisan make:migration add_foreign_keys_table

In dieser Datei fügen wir folgenden Code unter up() ein:

...
Schema::table('orders', function (Blueprint $table) {       
    $table->foreign('customer_id')->references('id')->on('customers');
});   
// und unter down() dann diesen Code:

Schema::table('orders', function (Blueprint $table) {            
     $table->dropForeign('orders_customer_id_foreign');                                                           
});

Was ist das up and down eigentlich?

Diese zwei Methoden werden von Laravel benötigt, wenn wir die Schemas in unsere Datenbank migrieren. Up dann für das bauen und down für das löschen, entfernen. Dazu bedienen wir uns dann wieder des artisan Commands:

php artisan migrate 
php artisan migrate:reset

Wichtig, falls es mal mit den Fremdschlüssel am Anfang nicht so klappt und ihr probleme habt die Tabellen unkompliziert zu löschen. Dafür gibt es den artisan befehl: wipe.

php artisan db:wipe

That it!

Installiere Node.js unter Ubuntu

Es gibt mehrere Möglichkeiten Node.js unter Ubuntu zu installieren. Ubuntu 18.04 beinhaltet im Standard Repository eine node.js Version. Diese wird einfach über apt insatlliert. Allerdings ist diese Version zwar eine stable Version aber nicht die aktuellste. Sie genügt eigentlich nur um sich mit node.js einwenig vertraut zu machen. Aber will man zum Beispiel mit VueJS oder React entwickeln, sollte man sich die aktuellste node.js Version installieren.

Installation mit dem Paketmanager apt

sudo apt update
sudo apt install nodejs
sudo apt install npm
nodejs -v

Installation unter Verwendung eines PPA

Zuerst insatlliert man das PPA (https://wiki.ubuntuusers.de/Paketquellen_freischalten/PPA/) um es später dann für den Packetmanager apt verfügbar zu machen. Mit curl laden wir ein Bash Script von nodesource runter. Achte hier auf die Versionsnummer und passe diese entsprechen an. In diesem Beispiel laden wir node 10 runter.

cd ~
curl -sL https://deb.nodesource.com/setup_10.x -o nodesource_setup.sh

Du kannst dir das gedownladete Script mal vim oder nano anschauen. Dann wird das Bash Script ausgeführt mit:

sudo bash nodesource_setup.sh

Nun können wir ganz normal mit dem Packetmanager apt node.js 10 installieren.

sudo apt install nodejs
nodejs -v
npm -v

In diesem Fall müssen wir npm nicht seperat installieren, da es auf diesem Weg bereits in der gedownloadeten Source enthalten ist.

Damit einige npm Pakete richtig funktionieren sollte man noch build-essential Paket installieren:

sudo apt install build-essential

Das wars!

Die ersten Schritte mit VueJS – Die Installation

Hast Du vor dir mal Vue JS anzuschauen? Dann ist dieser Artikel genau richtig. Hier zeige ich Dir wie man Vue JS bei dir auf dme Rechner zum laufen kriegt.

Man braucht für Vue JS node.js (https://nodejs.org). Hier könnt ihr node für Mac, Windows und Linux runterladen. Für Ubuntu User ist hier die Anleitung zur Node.js installation.

NodeJs Download Website

Danach checkt mal mit nodejs -v und npm -v ob Ihr node und den Node-Packetmanager installiert habt. Wenn ja, dann können wir nun Vue JS installieren.

Als erstes installieren wir nun die Vue-Cli mit

npm install -g @vue-cli

Mit

vue --version

könnt ihr nun im Terminal eure Vue Version checken.

Legt einen Ordner an, in dem ihr euer Test Vue mal installieren wollt und gebt in die Konsole ein:

vue create hello-world

Klickt Euch durch die Konfiguration durch und dann habt ihr euer erstes VueJS Projekt angelegt, welches ihr nun mit folgenden Cli command starten könnt.

npm run serve

Nachdem fleißig kompiliert wurde, erscheint im Konsolenfenster der Hinweis, dass Ihr unter localhost:8080 das du das neu angelegte Hello World Projekt betrachten kannst.

Achtet drauf, dass Du im Projektverzeichnis bist!

SeoTheater Autoren